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;
}

运行结果:

相关推荐
用户76241175670514 分钟前
第四章 流程控制结构
c++
Jack N15 分钟前
【Strapi 系列之五】前端怎么接?Next.js + Tailwind 拉取 Strapi 数据(含代码)
开发语言·前端·javascript·strapi
会编程的小孩1 小时前
Qt学习路线大纲图
c++
SuperHeroWu71 小时前
ArkGenie 的技术原理:从一段 SSE 到一个可交互 Surface
开发语言·php·交互
洁洁!1 小时前
手搓 C++ 线程池详细讲解以及如何面试应答
java·c++·面试
萝卜白菜。1 小时前
TongWeb生产环境配置规范之三:优化TongWeb启动速度
java·开发语言
企业解惑小助手1 小时前
上网行为监控软件有哪些?部署后终端卡顿、断网、审计缺失怎么办?一份完整故障排查手册
开发语言·php
利威尔xu2 小时前
万字详解 | Go 进阶(二)GC 三色标记:STW 从 10ms 压到 40μs,1 次 Full GC 让线上 P99 抖了 3 秒
开发语言·后端·性能优化·golang·高并发
坤坤子吖2 小时前
C++继承:继承的基本用法与访问规则
开发语言·c++·笔记·学习