静态成员:
普通成员变量每个对象各自有一份,静态成员一共就一份,为所有对象所共享
sizeof(class)时不会把类中的静态成员变量大小算进来,因为其不是放在对象的内部了
静态成员不具体作用于某一个对象
静态成员的访问:
1、类名::成员名
2、对象名.成员名,形式如此,但并不作用于对象
3、指针->成员名,形式如此,但并不作用于对象
4、引用.成员名,形式如此,但并不作用于对象
静态成员变量本质上是全局变量,哪怕一个对象不存在,类的静态成员变量也存在。
静态成员函数本质上是全局函数。
设置静态成员的目的是为了将和某些类紧密联系的变量和函数写到类里面,看上去像一个整体,便于理解和维护
必须在定义类的文件中对静态成员变量进行一次说明或初始化,否则编译能通过,链接不能通过。
class Rectangle{
int width;
int length;
static int totalNum;
static int totalArea;
public:
Rectangle(int w,int l){
width = w;
length = l;
totalNum++;
totalArea += width * length;
cout<<"construct:"<<totalNum<<"\t"<<totalArea<<endl;
}
~Rectangle(){
totalNum--;
totalArea -= width * length;
cout<<"destruct:"<<totalNum<<"\t"<<totalArea<<endl;
}
};
int Rectangle::totalNum = 0;
int Rectangle::totalArea = 0;
int main() {
Rectangle r1(
1,
2);
return
0;
}
注意:上述程序段是不安全的,当使用Rectangle类调用的是复制构造函数时,由于没有指定复制构造函数,系统使用缺省的复制构造函数,临时对象生成的时候没有增加total的总数,却在消亡的时候调用析构函数减少total的总数。
静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数,因为静态成员不专属于某个对象,访问的非静态成员到底来自哪个对象,说不通。
成员对象和封闭类:
一个类的成员变量是另一个类的对象。
包含成员对象的类叫封闭类。
注意:生成封闭类对象的时候,要明确对象中的成员对象是否需要初始化
定义封闭类的构造函数时,添加初始化列表:类名::构造函数(参数表):成员变量1(参数表),成员变量2(参数表)……{}
调用顺序:
封闭类生成对象时:先执行所有成员对象的构造函数,然后执行封闭类的构造函数。
封闭类中有多个成员对象时,构造函数的调用顺序和成员对象在类中的说明顺序一致(Type name )与在成员初始化列表中的出现顺序无关。
封闭类的对象消亡时:先执行封闭类的析构函数,再执行成员对象的析构函数。
class Tyer{
int a,b;
public:
Tyer(){
cout<<"no param construct"<<endl;
}
Tyer(int a1,int b1 ){
cout<<"two params construct"<<endl;
}
};
class Engine{
public:
Engine() {
cout << "engine construct" << endl;
}
};
class Car{
Tyer t;//说明对象,并没有调用构造函数
Engine e;
public:
Car(int a1,int b1):t(a1,b1){}//初始化才调用构造函数
};
int main() {
Car c(
1,
2);
return 0;
}