C++学习——静态成员和单例模式

静态成员变量

在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量,与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量属于某个类,所以对象共享。静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间了。

  1. 静态成员变量必须在类中声明,在类外定义

  2. 静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间

  3. 静态数据成员可以通过类名或者对象名来引用

静态成员变量

  1. static int m_Id; //静态成员变量,会共享数据
  2. 静态成员变量 在类内声明,在类外进行初始化
  3. 静态成员变量也是有权限的,私有静态成员变量类外不能访问
  4. 通过对象访问属性:Animal animal1; animal1.m_Id = 10;
  5. 通过类名访问属性:Animal::m_Id; 不会调用构造函数,因此访问不到构造函数里面的成员变量初始化,所以要把静态成员变量的初始化实现放在类外

静态成员函数

  • static void func();  //静态成员函数,数据共享,可以在类内进行实现
  • 不可以访问 普通成员变量;可以访问静态成员变量
  • 静态成员函数是有权限的
//静态成员变量和静态成员函数
class Animal
{
public:

	int m_A;         // 普通成员变量
	
	static int m_Id; //静态成员变量,会共享数据;静态成员变量 在类内声明,在类外进行初始化
	

	static void func()  //静态成员函数,数据共享,可以在类内进行实现
	{
		m_Id = 0;
		cout << "func的调用" << endl;
	}

	//普通成员函数 可以访问普通成员变量,也可以访问静态成员变量
	void myFunc()
	{
		m_A = 10;  //普通成员变量
		m_Id = 100;//静态成员变量
	}

private:
	static int m_other; //类外不能访问

};
int Animal::m_Id = 0;     // 类外初始化实现
int Animal::m_other = 10; //因为写了Animal也算是类内的

void test04()
{
	// 1、通过对象访问属性
	Animal animal1;
	animal1.m_Id = 10;

	Animal animal2;
	animal2.m_Id = 20;

	cout << "animal1: " << animal1.m_Id << endl; // 20 因为数据共享,输出都是20
	cout << "animal2: " << animal2.m_Id << endl; // 20  

	// 2、通过类名访问属性,不会调用构造函数,因此访问不到构造函数里面的成员变量初始化,所以要把静态成员变量的初始化实现放在类外
	cout << "通过类名访问属性: " << Animal::m_Id << endl;


	//静态成员函数
	animal1.func();
	animal2.func();
	Animal::func();
}

静态成员实现单例模式

单例模式(Singleton):一个类中只能实例出一个对象

如何实现呢??   请看下面的例子

将默认构造函数和拷贝构造函数私有化------>内部维护一个对象指针------>私有化唯一指针------>对外提供getInstance方法来访问这个指针

//静态成员实现单例模式
//一个类中只能实例出一个对象Singleton(单例)
class ChairMan
{

private:
	ChairMan()
	{
		cout << "单例模式创建" << endl;
	}

	ChairMan(const ChairMan &c)
	{

	}

public:
	static ChairMan *getInstance() //不加static只能通过对象访问,现在是通过类名在访问
	{
		return singleMan;
	}
	//static ChairMan * singleMan;
	
private:
	static ChairMan * singleMan; //私有化,防止被外部修改,那么就提供get方法

};

ChairMan * ChairMan::singleMan = new ChairMan; // 因为在ChairMan作用域内,其实就是在类内

void test05()
{
	//创建多个对象其实就是调用多次构造函数,解决方法是将构造函数私有化
	//ChairMan c1;
	//ChairMan *c2 = new ChairMan;

	//将构造函数私有化后
	/*----------------------------将构造函数私有化后--------------------------------------*/
	//ChairMan::singleMan;  //保证它只有一个,且在编译阶段就已经完成了
	//ChairMan *c1 = ChairMan::singleMan;
	//ChairMan *c2 = ChairMan::singleMan;  //c1和c2是一样的
	
	/*-------------------为了防止c1或c2被外部修改,就将singleMan也私有化-------------------*/
	ChairMan *cm1 = ChairMan::getInstance();
	ChairMan *cm2 = ChairMan::getInstance(); //cm1与cm2相同
	if (cm1 == cm2)
	{
		cout << "cm1与cm2相同" << endl;
	}
	else
	{
		cout << "cm1与cm2不相同" << endl;
	}

	//ChairMan *cm3 = new ChairMan(*cm2); //cm2与cm3不相同
	/*-------------------解决这种方法:就将拷贝构造函数也私有化------------------------------*/
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值