析构函数调用顺序,const型对象,对象函数共用
1. 析构函数的调用顺序:
单个对象创建时其构造函数的调用顺序:
1. 调用父类的构造函数
2. 调用内部成员变量的构造函数,变量间的调用顺序和声明顺序相同
3. 调用自己的构造函数
多个或者单个对象销毁时其析构函数的调用顺序和构造函数相反
#include <stdio.h> class Member { const char* ms; public: Member(const char* s) { printf("Member(const char* s): %s\n", s); ms = s; } ~Member() { printf("~Member(): %s\n", ms); } }; class Test { Member mA; Member mB; public: Test() : mB("mB"), mA("mA") { printf("Test()\n"); } ~Test() { printf("~Test()\n"); } }; Member gA("gA"); int main() { Test t; // 构造顺序:gA.Member() mA.Member() mB.Member() Test.Test() // 析构顺序:Test.~Test() mB.~Member() mA.~Member() gA.~Member() return 0; }
析构函数调用规则如下:
1. 存在于栈和全局的对象在析构时:构造顺序和析构顺序相反。
2. 存在于堆对象的对象在析构时:析构顺序域delect调用顺序相反。
2. const修饰的对象:
const修饰的对象是只读对象(成员变量属性变为只读,成员函数属性不变)
const成员函数:
const对象只可以调用const成员函数,不可调用对象中其他非const函数
const成员函数中只能够调用const成员函数,不可调用对象中其他非const函数
const成员函数不可以直接修改成员变量的值
const成员函数定义:
Type ClassName::Function(Type p) const
类中函数的声明和实际函数的定义都要带const关键字
#include <stdio.h> class Test { int mi; public: Test(int i); Test(const Test& t); int getMi() const; }; Test::Test(int i) { mi = i; } Test::Test(const Test& t) { } int Test::getMi() const { return mi; } int main() { const Test t(1); printf("t.getMi()\n",t.getMi()); // error const成员只可以调用对象中的const成员函数 return 0; }
3. 每个对象都有自己的一套成员变量(属性),所有的对象共享同一套成员函数(方法)。
原因:代码段存放在代码段不可添加删除。变量存放于堆栈静态存储区可以添加删除。
如何让方法访问对应对象的属性:成员函数(方法)中包含一个指针:this。指向当前调用成员函数的对象在内存的首地址。
#include <stdio.h> class Test { int mi; public: int mj; Test(int i); Test(const Test& t); int getMi(); void print(); }; Test::Test(int i) { mi = i; } Test::Test(const Test& t) { mi = t.mi; } int Test::getMi() { return mi; } void Test::print() { printf("this = %p\n", this); } int main() { Test t1(1); Test t2(2); Test t3(3); printf("t1.getMi() = %d\n", t1.getMi()); printf("&t1 = %p\n", &t1); // addr1 this指针指向的地址是对象的首地址 t1.print(); // addr1 printf("t2.getMi() = %d\n", t2.getMi()); printf("&t2 = %p\n", &t2); // addr2 addr1 与 addr2 地址不同说明每套对象都有不同的地址 t2.print(); // addr2 printf("t3.getMi() = %d\n", t3.getMi()); printf("&t3 = %p\n", &t3); // addr3 t3.print(); // addr3 return 0; }