类定义
class Account{
public:
static double rate(){
return interestRate;
}
private:
static double interestRate;
static double initRate()
{
return 1;
}
};
double Account::interestRate = 0;
动机
一些成员变量没必要每个对象都持有一份,比如银行账户类的利率。还能减小内存占用。
静态成员函数
1.不能声明为const
静态成员函数属于大家,所以没有this指针,而const是修饰this指针的,所以静态成员函数不能声明为const
2.访问方式(成员变量同理)
既可以通过类作用域访问,也能通过对象,指针,引用访问(以前经常误会成只能通过类访问)
double r = Account::rate();
Account ac1;
Account *ac2 = &ac1;
r = ac1.rate();
r = ac2->rate();
静态成员变量
1.初始化时机
因为静态成员变量属于所有对象,所以不能在构造函数初始化,需要在类外初始化。
2. 可以调用其他static的private函数和成员进行初始化
double Account::interestRate = initRate();
3.static const整数类型
可以在类里初始化,但必须用常量表达式。在类外也必须定义一下,但不用带初始值,否则外面的函数找不到这个变量。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Account
{
public:
static constexpr int period = 30;
};
void f(const int&)
{
}
void g(const int)
{
}
int main() {
cout<<Account::period<<endl; //为啥这个找到了
f(Account::period); //xxx,找不到,undefined reference to `Account::period'
g(Account::period); //没错
return 0;
}
解决方法是在类外定义使之地址可见
constexpr int Account::period;
问题:
为啥cout没错?为啥函数形参为const int 没错? 为啥函数形参为const int& 错了?
推测是想引用地址就必须在同一块下可见才行
番外:
cout是个流对象,或者说是ostream这个类的对象,该类内部有输出缓冲区,当执行cout << x的时候,其实就是调用了ostream的operator<< 方法,该方法是对<<运算符的重载,该方法的参数即是x。
operator<<方法返回ostream类的引用,即该类对象自身,所以cout << x 语句可以做左值,即支持连续调用: cout << x << y.....
x变量内容拷贝到缓冲区中,ostream内部会根据某种缓冲机制(全缓冲,行缓冲,无缓冲)将缓冲区的内容输出到屏幕终端。
执行cout << a++时,先打印a,之后将a加一,同理类推。
所以cout << (a++) << (a++) << (a++) << endl;语句打印三次a变量,每次执行同时将a加一,最后endl即将缓冲区所有内容输出,同时打印换行。
执行结果是: 1 2 3
4. static变量的优势
1.适用于非完全类型
class Bar{
private:
static Bar mem1; //正确,但外面的初始化咋整呢?
Bar * mem2;
Bar mem3; //xxx
};
Bar Bar::mem1 = Bar(); //这样吗?
2.可以作为默认实参
class Screen{
public:
Screen &clear(char = bkGround);
private:
static const char bkGround;
};
这俩之所以可以还是时间先后顺序。