C++ 类的static成员(static members)


目录
  • 基本概念
  • 静态成员变量(Static data members)
  • 静态成员函数(Static member functions)
  • 只可以使用静态成员的场景
  • 代码示例
  • 总结

基本概念

引例:银行账户类中需要一个数据成员来表示利率,利率变动时,所有的对象都用新的利率,利率是和类相关联而不和每个对对象关联,此时利率便适合作为静态成员。

class Account {
public:
 static void SetInterestRate(double new_interest_rate);
 static double GetInterestRate();
private:
 static double interest_rate_;
};
double Account::interest_rate_ = 0.001;
void Account::SetInterestRate(double new_interest_rate) {
    interest_rate_ = new_interest_rate;
}
double Account::GetInterestRate() {
 return interest_rate_;
}
  1. 类的静态成员不与任何对象相关联

  2. static在类内声明时使用,类外初始化变量或者定义函数时不用加

  3. 静态成员遵循类的public,private,protected访问规则

静态成员变量(Static data members)

  1. 存储在全局静态区,当计算某个对象的大小时,不会将其计算在内.
  2. 类内声明后会有一个默认值
  3. 通常在类外进行初始化

静态成员函数(Static member functions)

  1. 没有this指针
  2. 不可以为virtual, const, volatile
  3. 可以通过类名直接调用,也可以用常规方式调用
  4. 只能访问静态成员
  5. 类内声明时加上static关键字,类外定义时不需要加。
  6. 可以在类内定义,也可以在类外定义

只可以使用静态成员的场景

  1. 静态数据数据成员可以是不完全类型(声明之后,定义之前).
  2. 静态数据成员的类型可以是它所属类的类型,非静态成员只能声明为它所属类的指针或者引用
  3. 可以使用静态成员作为默认实参

代码示例

class A {
public:
    // 静态成员变量不能在构造函数中初始化
    A(): val(0) {}
    // 类内声明static成员函数
    static void PubFunc();
   // 可以类内直接定义static成员函数
    static void PubFunc1() {
        cout << __func__ << endl;
    }
    static int pub_val_;
        
private:
    int val;
    static int pri_val_;
    static void PriFunc();
    static void PriFunc1();
};
// 类外初始化时不需要加static关键字
int A::pub_val_ = 1;
int A::pri_val_ = 6;
// 类外定义时不需要加static关键字
// 静态成员函数只能访问静态成员
void A::PubFunc() {
    cout << __func__ << endl;
    PriFunc1();
}
void A::PriFunc() {
    cout << __func__ << endl;
    cout << pri_val_;
    cout << pub_val_;
    // wrong:没有this指针
    // cout << this->pri_val_;
}
void A::PriFunc1() {
    cout << __func__ << endl;
}

class B; // 类的前向声明---不完全类型
class C {
    static C sta_c_;	// 静态成员可以是不完全类型
    C* pc_; // 指针成员可以是不完全类型
    C& refc_; // 引用成员可以是不完全类型
    C c_; // wrong
};

int main(int argc, char** argv)
{
    A a;
    A* p_a = &a;
    A& ref_a = a;

    // 访问成员变量
    cout << "A::pub_val_" << A::pub_val_ << endl;
    cout << "a.pub_val_" << a.pub_val_ << endl;
    cout << "p_a->pub_val_" << p_a->pub_val_ << endl;
    cout << "ref_a.pub_val_" << ref_a.pub_val_ << endl;
    // cout << a.pri_val_ << endl; // 无法访问private成员

    // 多个对象共享静态成员
    A a1;
    cout << "a.pub_val_:" << a1.pub_val_ << endl;
    a1.pub_val_++;
    cout << "a1.pub_val_:" << a1.pub_val_ << endl; 
    cout << "a.pub_val_:" << a.pub_val_ << endl;
    
    // 访问成员函数
    // 通过类名直接调用static成员函数
    A::PubFunc();
    A::PubFunc1();
    // 常规方式调用
    a.PubFunc();
    p_a->PubFunc();
    ref_a.PubFunc();
    
    return 0;
}

总结

将静态成员和普通成员多进行对比