静态成员变量
在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量,与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量属于某个类,所以对象共享。静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间了。
-
静态成员变量必须在类中声明,在类外定义
-
静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间
-
静态数据成员可以通过类名或者对象名来引用
静态成员变量
- static int m_Id; //静态成员变量,会共享数据
- 静态成员变量 在类内声明,在类外进行初始化
- 静态成员变量也是有权限的,私有静态成员变量类外不能访问
- 通过对象访问属性:Animal animal1; animal1.m_Id = 10;
- 通过类名访问属性: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不相同
/*-------------------解决这种方法:就将拷贝构造函数也私有化------------------------------*/
}