静态成员(static)

static修饰的成员变量/函数。

可以通过对象(对象.静态成员)、对象指针(对象指针->静态成员)、类访问(类名::静态成员)。

静态成员变量

静态成员变量存储在数据段(全局区,类似于全局变量),整个程序运行过程中只有一份内存。

对比全局变量,它可以设定访问权限(publicprotectedprivate),达到局部共享的目的。

必须初始化,必须在类外面初始化,初始化时不能带static,如果类的声明和实现分离(在实现.cpp中初始化)。

静态成员函数

内部不能使用this指针(this指针只能用在非静态成员函数内部)。

不能是虚函数(虚函数只能是非静态成员函数)。

内部不能访问非静态成员变量/函数,只能访问静态成员变量/函数。

非静态成员函数内部可以访问静态成员变量/函数。

构造函数、析构函数不能是静态。

当声明和实现分离时,实现部分不能带static

class Car
{
public:
    static int price;

    static void run()
    {

    }
};

// 初始化必须要在外面
int Car::price = 0;

int main()
{
    Car c1;
    c1.price = 10;
    c1.run();

    Car *c2 = new Car();
    c2->price = 20;
    c2->run();
    
    Car::price = 30;
    Car::run();

    return 0;
}

应用

单例模式

class Person
{
private:
    static Person *me;
    Person() {  }
    ~Person() {  }
    // 拒绝 *p1 = *p2;
    void operator=(const Person &p) {  }
    // 拒绝 Person *p2 = new Person(*p1);
    Person(const Person &p) {  }
public:
    static Person *get_instance()
    {
        if ( Person::me == NULL )
            Person::me = new Person();
        return Person::me;
    }
    
    static void destroy_instance()
    {
        if ( Person::me != NULL )
        {
            delete Person::me;        
            Person::me = NULL;            
        }
    }

    void say()
    {
        printf("Hello~\n");
    }
};

Person *Person::me = NULL; // 完全可以在这里初始化?

int main()
{
    Person *p1 = Person::get_instance();
    return 0;
}

const成员

const成员:被const修饰的成员变量、非静态成员函数。

const成员变量

必须初始化(类内部初始化),可以在声明的时候直接初始化赋值。

staticconst成员变量还可以在初始化列表中初始化。

class A
{
public:
    // 初始化方式1
    // const int a = 10;
    const int a;
    // 初始化方式2
    A() :a(0)
    {
        
    }
};

const成员函数(非静态)

const关键字写在参数列表后面,函数的声明和实现都必须带const

内部不能修改非static成员变量。

内部只能调用const成员函数、static成员函数。

const成员函数可以调用const成员函数。

const成员函数和非const成员函数构成重载。

const对象(指针)优先调用非const成员函数。

const对象(指针)只能调用const成员函数、static成员函数。

class A
{
public:
    void func() const;
};

void A::func() const
{

}

引用类型成员

弓引用类型成员变量必须初始化(不考虑static情况)。

在声明的时候直接初始化。

通过初始化列表初始化。

class A
{
private:
    int a;
    int &b = a;
public:
    A(int &b) :b(b) {}
};