C++陷阱之一(两个类在组合关系下构造函数的调用位置)

偶然发现,原来一些情况不使用初始化列表会出错

带大家看一段代码

一个Person类和一个Phone类,其中Phone作为Person类的一部分,这种关系在c++里称为组合。

大家可能都知道组合关系构造函数的调用顺序是被包含的类先构造,外部的类再构造,析构顺序刚好相反。。那么被包含的类在何时哪个位置被调用呢?为什么我们创建外部类,内部类的构造函数和析构会被自动调用呢?

其实这一切都是已经被编译器安排好了。编译器执行了类似这样的代码

构造时:Person::Perosn(...):Phone() {......}

析构时:Person::~Person(){....~Phone()}

#include<iostream>
using namespace std;

class Phone{
public:
	Phone(string PhoneName){
		cout<<"Phone的构造函数"<<endl;
		m_PhoneName = PhoneName;
	}
	~Phone(){
		cout<<"Phone的析构函数"<<endl;
	}
	string m_PhoneName;
};
class Person{
public:
	Person(string name,string PName){
		cout<<"Perosn的构造函数"<<endl;
		m_p = PName;
		m_name = name;
	}
	/*
	Person(string name,string PName):m_p(PName),m_name(name){
		cout<<"Perosn的构造函数"<<endl;
	}
	*/
	~Person(){
		cout<<"Perosn的析构函数"<<endl;
	}
	Phone m_p;
	string m_name; 
};


void test01(){
	Person p1("张三","苹果");
	cout<<p1.m_p.m_PhoneName<<endl;
}

int main(){
	test01();
	system("pause");
	return 0;
}

代码运行起来会怎么样,报错没有可调用的构造函数,为什么呢?

原因就出在Person类的构造函数。我们希望的是什么?在 m_p = PName 时再调用Phone类的有参构造,创建一个已经初始化的Phone对象作为Person对象的成员,但是正如上边我提到的,构造函数的调用提前了,调用的位置是Person构造函数形参列表的后边(前面我标红的位置),而在这里调用的是无参构造,恰好我们没有提供,于是就出错了。

怎么解决----》代码中我注释掉的 初始化列表 写法就可以,初始化列表可以起到赋值的作用,同时位置刚好又处在 Person构造函数形参列表后边,成功调用Phone类的有参构造,代码运行输出正确结果。

所以大家平常写代码,可以的情况下一定要使用初始化列表,能让我们代码看起来更简洁大气,效率更高,出错可能最小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值