一、构造函数与析构函数的调用顺序
(1)、单个对象创建时构造函数的调用顺序
1.调用父类的构造过程
2.调用成员变量的构造函数(调用顺序与声明顺序相同)
3.调用类自身的构造函数
4.析构函数与对应的构造函数调用相反(先类自身再类成员最后父类)
(2)、多个对象析构时
析构顺序与构造顺序相反
#include <iostream>
using namespace std;
class Member
{
const char* ms;
public:
Member(const char* s)
{
cout << "Member(const char* s):" << s << endl;
ms = s;
}
~Member()
{
cout << "~Member(): "<< ms << endl;
}
};
class Test
{
Member mA;
Member mB;
public:
Test() : mB("mB"), mA("mA")
{
cout << "Test()" << endl;
}
~Test()
{
cout << "~Test()" << endl;;
}
};
Member gA("gA");
int main()
{
Test t;
return 0;
}
打印结果:
Member(const char* s):gA
Member(const char* s):mA
Member(const char* s):mB
Test()
~Test()
~Member(): mB
~Member(): mA
~Member(): gA
结论:
1.对于栈对象和全局对象,类似于入栈和出栈顺序,最后构造的会最先被析构
2.对于堆对象,析构顺序与delete调用顺序有关
二、const关键字是否可以修饰类对象
1.const可以修饰对象,变成只读对象
2.只读对象的成员变量不允许改变
3.只读对象是编译阶段的概念,运行时无效
c++的const成员函数
1.const对象只能调用const的成员函数
2.const成员函数中只能调用const成员函数
3.const成员函数中不能直接改写成员变量的值
4.const成员函数的定义:函数声明之后函数体之前加上const关键字
#include<iostream>
using namespace std;
class Test
{
private:
int mi;
public:
int mj;
Test(int i);
Test(const Test& obj);
int getMi() const;
};
Test::Test(int i)
{
mi = i;
}
Test::Test(const Test& obj)
{
mi = obj.getMi();//const Test& obj说明是只读的,如果getMi()不是只读的,这行就会出错
}
int Test::getMi() const
{
//mi = 5;//只读对象的成员变量不允许改变
return mi;
}
int main()
{
const Test t(1);
// t.mj = 5;//只读对象的成员变量不允许改变
cout << t.getMi()<<endl;
return 0;
}
三、成员函数和成员变量都是隶属于具体对象的么?
1.从面向对象的角度看:对象由属性(成员变量)和方法(成员函数)构成
2.从程序运行角度:对象由数据和函数构成
数据位于栈、堆和全局数据区
函数只能位于代码段(所以所有对象共有一套成员函数)
#include <iostream>
using namespace std;
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()
{
cout <<"this = " << this << endl;
}
int main()
{
Test t1(1);
Test t2(2);
Test t3(3);
cout << "t1.getMi() = " << t1.getMi() << endl;
cout << "&t1 = " << &t1 << endl;
t1.print();
cout << "t2.getMi() = " << t2.getMi() << endl;
cout << "&t2 = " << &t2 << endl;
t2.print();
cout << "t3.getMi() = " << t3.getMi() << endl;
cout << "&t3 = " << &t3 << endl;
t3.print();
return 0;
}
打印结果:
t1.getMi() = 1
&t1 = 0xbfc94068
this = 0xbfc94068
t2.getMi() = 2
&t2 = 0xbfc94070
this = 0xbfc94070
t3.getMi() = 3
&t3 = 0xbfc94078
this = 0xbfc94078
结论:
1.每个对象都拥有自己独立的属性(成员变量)
2.所有对象共享类的方法(成员函数)
3.方法能够直接访问类的属性(成员函数只有一套,成员函数能够访问对应类的所有对象的成员变量)
4.那程序怎么知道是哪个对象调用了成员函数呢(方法中的隐藏参数this用于指代当前对象)
小结:
1.对象的析构顺序与构造顺序相反
2.const关键字能够修饰对象,得到只读对象
3.只读对象只能调用const成员函数
4.所有对象共享类的成员函数
5.隐藏的this指针用于表示当前对象从而分辨哪个对象调用了成员函数