经典问题解析

本文详细介绍了C++中对象构造与析构的顺序,强调了栈对象和全局对象析构的逆序原则以及堆对象的析构与delete操作的关系。同时,讨论了const关键字修饰对象的特性,指出const对象为只读且只能调用const成员函数。此外,还阐述了类成员函数和成员变量与对象的关系,强调每个对象拥有独立的属性,而成员函数是共享的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经典问题解析

一、关于析构的疑问

当程序中存在多个对象的时候,如何确定这些对象的析构对象

1、单个对象创建时,构造函数的调用顺序:

  • 1)调用父类的构造过程
  • 2)调用成员变量的构造函数(调用顺序与声明顺序相同)
  • 3)调用类自身的构造函数

析构函数与对应构造函数的调用顺序相反

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()
{
	printf("-----------main begin-----------\n");
	
	Test t;

	printf("-----------main end-----------\n");
	return 0;
}

/*
运行打印结果如下:
Member(const char* s):gA
-----------main begin-----------
Member(const char* s):mA
Member(const char* s):mB
Test()
-----------main end-----------
~Test()
~Member():mB
~Member():mA
~Member():gA
*/

答案

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

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

二、关于const对象的疑问

const关键字能否修饰类的对象?如果可以,有什么特性

答案

  • const关键字能够修饰对象

  • const修饰的对象为只读对象

  • 只读对象的成员变量不允许被改变

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

C++中的const成员函数

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

const成员函数的定义

Type ClassName::function(Type p) const
#include <stdio.h>

class Test
{
	int mi;
public:
	int mj;
	Test(int i);
	Test(const Test& t);
	int getI()const;
};

Test::Test(int i)
{
	mi = i;
}

Test::Test(const Test & t)
{
	mi = t.mi;
}

int Test::getI()const
{
	//const函数不能修改成员值值
	//mi = 2;
	return mi;
}

int main()
{
	printf("-----------main begin-----------\n");
	
	const Test t = 1;
	
	//const对象不能调用成员函数,只能调用const修饰的成员函数
	printf(" t.getI() = %d\n",t.getI());
	
	printf("-----------main end-----------\n");
	return 0;
}



三、关于类成员的疑问

成员函数成员变量都隶属于具体对象吗?

分析

  • 面相对象的角度
    • 对象由**属性(成员变量)方法(成员函数)**构成
  • 程序运行的角度
    • 对象由数据函数构成
      • 数据可以位于,和全局数据区
      • 函数只能位于代码段

结论

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

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

  • 方法能够直接访问对象的属性

  • 方法中的隐藏参数this用于指代当前对象

#include <stdio.h>

class Test
{
	int mi;
public:
	int mj;
	Test(int i);
	Test(const Test& t);
	int getI();
	void print();
};

Test::Test(int i)
{
	mi = i;
}

Test::Test(const Test & t)
{
	mi = t.mi;
}

int Test::getI()
{
	return mi;
}

void Test::print()
{
	printf("this = %p\n", this);
}

int main()
{
	printf("-----------main begin-----------\n");

	Test t1 = 1;
	Test t2 = 2;
	Test t3 = 3;
	
	printf(" t1.getI() = %d\n",t1.getI());
	printf(" &t1 = %p\n",&t1);
	t1.print();
	
	printf(" t2.getI() = %d\n",t2.getI());
	printf(" &t2 = %p\n",&t2);
	t2.print();
	
	printf(" t3.getI() = %d\n",t3.getI());
	printf(" &t3 = %p\n",&t3);
	t3.print();
	
	printf("-----------main end-----------\n");
	return 0;
}


/*
-----------main begin-----------
 t1.getI() = 1
 &t1 = 0x7fffad8e2120
this = 0x7fffad8e2120
 t2.getI() = 2
 &t2 = 0x7fffad8e2130
this = 0x7fffad8e2130
 t3.getI() = 3
 &t3 = 0x7fffad8e2140
this = 0x7fffad8e2140
-----------main end-----------
*/

四、小结

  • 对象的构造顺序析构顺序相反
  • cosnt关键字可以修饰对象,得到只读对象
  • 只读对象只能调用const成员函数
  • 所有对象共享类的成员函数
  • 隐藏的this指针用于表示当前的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值