C++——析构函数的调用顺序、const修饰对象、类成员

1.析构顺序和构造顺序

(1)单个对象创建时构造函数的调用顺序

①调用父类的构造过程 ②调用成员变量的构造函数(调用顺序与声明顺序相同)③调用类自身的构造函数

析构函数与对应构造函数的调用顺序相反 :③②①

(2)示例:

复制代码
#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; 
	return 0;
}

运行结果:

(3)析构顺序

①对于栈对象和全局对象,类似于入栈和出栈的顺序,最后构造的对象被最先析构

⑤堆对象的析构发生在使用delete的时候,与delete的使用顺序相关

2.const修饰对象

(1)const关键字能够修饰对象

(2)const修饰的对象为只读对象

(3)只读对象的成员变量不允许被改变

(4)只读对象是编译阶段的概念,运行时无效

(5)const对象只能调用const成员函数,const成员函数中只能调用const成员函数,const成员函数中不能直接改写成员变量的值

复制代码
#include <stdio.h>
class Test {
	int mi;
public:
	int mj;
	Test(int i);
	Test(const Test& t);
	int getMi();
};
Test::Test(int i) {
	mi = i;
}
Test::Test(const Test& t) {

}
int Test::getMi() {
	return mi;
}
int main() {
	const Test t(1);
	// t.mj = 1000; 报错,因为t是只读对象,不能修改成员变量的值
	
	//printf("t.getMi()=%d\n", t.getMi()); 报错,因为t是const对象,只能调用const成员函数
	return 0;
}

如果想要调用getMi()函数,则需要将该成员函数变为const函数

复制代码
#include <stdio.h>
class Test {
	int mi;
public:
	int mj;
	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);
	// t.mj = 1000; 报错,因为t是只读对象,不能修改成员变量的值
	
	printf("t.getMi()=%d\n", t.getMi()); // t.getMi()=1
	return 0;
}

(1)从面向对象的角度,对象由属性(成员变量)和方法(成员函数)构成

(2)从程序运行的角度,对象由数据和函数构成,数据可以位于栈、堆和全局数据区中,函数只能位于代码段中

结论:

(1)每一个对象拥有自己独立的属性(成员变量)

(2)所有的对象共享类的方法(成员函数)

(3)方法能够直接访问对象的属性

(4)方法中的隐藏参数 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; //mi是私有属性,但是仍可访问,因为Test(const Test& t)是成员函数,可以访问对应对象的成员变量
}
int Test::getMi() {
	return mi;
}
void Test::print() {
	printf("this=%p\n", this); //this指针指向当前调用该函数的对象地址
}
int main() {
	Test t1(1); 
	Test t2(2);
	Test t3(3);
	
	printf("t1.getMi()=%d\n", t1.getMi());
	printf("&t1=%p\n", &t1);
	t1.print();
	printf("t2.getMi()=%d\n", t2.getMi());
	printf("&t2=%p\n", &t2);
	t2.print();
	printf("t3.getMi()=%d\n", t3.getMi());
	printf("&t3=%p\n", &t3);
	t3.print();
	return 0;
}

运行结果:

相关推荐
2401_889884662 分钟前
嵌入式C++测试框架
开发语言·c++·算法
1104.北光c°3 分钟前
我理解的Leaf号段模式:美团分布式ID生成系统
java·开发语言·笔记·分布式·github·leaf
DREW_Smile7 分钟前
字符函数和字符串函数2
c语言·开发语言
wjs202418 分钟前
CSS 颜色
开发语言
无巧不成书021820 分钟前
Java数值字面量速查表
java·开发语言·python·开发者·字面量
小鸡吃米…20 分钟前
测试线程应用程序
开发语言·python
python开发笔记21 分钟前
python(79) 底层代码追踪工具
开发语言·python
kgduu22 分钟前
js之错误处理
开发语言·前端·javascript
Bert.Cai22 分钟前
Python函数的定义与调用
开发语言·python
美式请加冰24 分钟前
模拟的介绍和使用
java·开发语言·算法