关于“对象成员”的析构函数

本文通过C++代码示例解释了构造函数和析构函数在创建和销毁对象时的调用情况,特别关注了初始化列表与构造函数内赋值的区别,指出前者仅构造一次,后者可能因嵌套类而构造多次。

#include<iostream>
#include<string>

using namespace std;
 

class Phone { //手机类
public:
	string m_PName;

	Phone() {};

	Phone(string pName) {
		m_PName = pName;
		
		cout <<"Phone类的构造函数被调用" << endl;
	}

	~Phone() {
		cout << "Phone类的析构函数的调用" << endl;
	}
};

class Person { //人类
public:
	//手机
	string m_Name;
	//手机
	Phone m_Phone;

	Person(string name, string pName) {
		m_Name = name;
		m_Phone = pName;

		cout << "Person类的构造函数被调用" << endl;
	}

	~Person() {
		cout << "Person类的析构函数被调用" << endl;
	}
};

void test01() {
	Person p=Person("张三","苹果");

	cout << "m_Name:" << p.m_Name << "m_Phone:" << p.m_Phone.m_PName << endl;
}
int main() {
	test01();
} 

由上述代码,我们可以得到以下结果:

从上图中,我们可以看出,Phone类的析构函数被调用了两次。

让我们来分析上述代码:

void test01() {
    Person p = Person("张三", "苹果");

    cout << "m_Name:" << p.m_Name << "m_Phone:" << p.m_Phone.m_PName << endl;
}

在这个函数中,我创建了一个 Person 对象 p,并通过 Person("张三", "苹果") 的方式进行初始化。这实际上会发生两个步骤:

  1. 构造 Phone 对象:

    通过 Phone("苹果") 构造一个临时的 Phone 对象,然后拷贝到 m_Phone 成员中。
  2. 构造 Person 对象:

    Person 对象 p 的构造函数被调用,其中包括 m_Phone 成员的构造。

因此,这里会调用两次 Phone 类的构造函数。第一次是创建临时对象,第二次是在 Person 对象中构造 m_Phone

接下来,当 test01 函数执行完毕时,Person 对象 p 超出了作用域,导致 Person 类的析构函数被调用。由于 Person 类中有一个 Phone 类的成员 m_Phone,这也导致了 Phone 类的析构函数被调用。

因此,Phone 类的析构函数被调用两次是因为它在两个地方被构造(test01 函数内和 Person 类内),相应地也被析构两次。

但,当我将“Person类的构造函数”写成以下形式:

Person(string name, string pName) : m_Name(name), m_Phone(pName) {
    cout << "Person类的构造函数被调用" << endl;
}

可以得到以下结果:

从上图中,我们可以看出,Phone类的析构函数只被调用了一次。

为什么? 让我们来分析,在C++中,初始化列表和在构造函数里赋值有什么区别,就可以得出该结论。

初始化列表:在构造函数的头部,通过成员初始化列表对类的成员进行初始化。

这是在构造函数体执行之前完成的。成员初始化列表直接在对象创建时初始化成员,避免了先调用默认构造函数,再进行赋值的开销。

在构造函数里赋值:

在构造函数体内,通过赋值语句来给成员变量赋初值。这是在对象创建后,构造函数体执行时进行的。

如果成员是一个类对象,这种方式会调用该类对象的默认构造函数,然后再通过赋值操作进行初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值