Classes sometimes need members that are associated with the class, rather than with individual objects of the class type. (就是说到目前为止,class 中的每一个mem都还是代表自己的obj的行为、表现的。但是有的时候我们就是需要让一个mem代表的是class,而不是obj)

class Account { 
public:
    void calculate() { amount += amount * interestRate; } 
	static double rate() { return interestRate; } 
	static void rate(double); 
private:
	std::string owner; 
	double amount; 
	static double interestRate; 
	static double initRate(); 
};
 
void Account::rate(double newRate) { 
	interestRate = newRate; 
}
double Account::interestRate = initRate();

Using a Class static Member

// 1. directly through the scope operator  
double r;   
r = Account::rate();  // access a static member using the scope operator  
// 2. of the class type to access a static member  
Account ac1;   
Account * ac2 = &ac1;  
// equivalent ways to call the static member rate function   
r = ac1.rate();  // through an Account object or reference   
r = ac2->rate();  // through a pointer to an Account object  
// 3. Member functions can use static members directly  
class Account {   
public:  
 void calculate() { amount += amount * interestRate; }   
private:  
 static double interestRate;  
 // remaining members as before   
};  

Defining static Members

  • For member function, like any other member functions, we can define inside or outside. And you don’t need to repeat static again. (就是说,不看class内部不知道外面的是static还是normal)

  • For data member, because static data members are not part of individual object, so we can not initialize it inside a class. (难道每次create一个新obj的时候,都要更新静态量吗?)

    • With one exception. When the static data member is 1. const intergral type; 2. constexpr of literal type

因此,static data member 就像全局变量一样,定义在最外面,持续到程序结束。 (其余真的跟正常的func, data很像,域解析…private…)

The Exception

对于那些常量,常量字面量,我们可以提供 in-class initializers (没说理由)

⚠️ 注意:但要注意,如果你想要在class外面使用内部的这些,还是需要外面定义,只不过不再需要提供initializer了

Usage

  • a static data member can have incomplete type
  • we can use a static member as a default argument