C++中构造函数的两种写法

对于一个C++刚入门的小盆友来说,构造函数怎么写还不简单么?然而C++中构造函数的写法不止一种,而且从效果和性能上来说并不相同。先看两种构造函数的写法,找到其区别。

写法一(我赌一包辣条很多人没见过这种写法):

#include <iostream>
using namespace std;

template <typename Type>
class testClass {
public:
	// 构造函数 
	testClass(Type key);
	
	// 参数
	int defaultValue;
	Type keyValue;
};

template <typename Type>
testClass<Type>::testClass(Type key):defaultValue(10),keyValue(key){}

int main() {
	testClass<int> test(20);
	cout<<"defaultValue: "<<test.defaultValue<<endl;
	cout<<"keyValue: "<<test.keyValue<<endl;
	return 0;
} 

写法二(熟悉的味道!课本上教的就是这种写法):

#include <iostream>
using namespace std;

template <typename Type>
class testClass {
public:
	// 构造函数 
	testClass(Type key);
	
	// 参数
	int defaultValue;
	Type keyValue;
};

template <typename Type>
testClass<Type>::testClass(Type key) {
	this->defaultValue = 10;
	this->keyValue = key;
} 

int main() {
	testClass<int> test(20);
	cout<<"defaultValue: "<<test.defaultValue<<endl;
	cout<<"keyValue: "<<test.keyValue<<endl;
	return 0;
}

 

方法一叫成员初始化列表,可以将方法一的构造函数格式归纳为: 类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表)... { 类的初始化 }    

方法二即为比较容易理解的赋值方式。

 

下面考量一下这两种写法在运行时的区别。

一般地这两种构造方法并没有太大的区别,在效率上也基本一致。在这里我推荐你使用第一种初始化列表方法,那么为什么会这样累?在《Effective C++》中条款04中有解释以上两种初始化的区别:

方法一应该叫作初始化,方法二应该叫作赋值。二者是有本质的区别的。

C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。因此方法二的构造函数内属性不能算是被初始化,是被赋值了。初始化发生的时间更早,发生在这些成员的default构造函数被自动调用之时。使用方法二的构造函数需要执行两次copu构造:defaultValue以10为初值进行copy构造,keyValue以key为初值进行copy构造。因此理论上使用方法一的成员初始化列表(member initialization list)方式的效率更高,因为比起先调用default构造函数然后再调用copy assignment操作符,单只调用一次copy构造函数是比较高效的。

也就是说采用方法二的话,构造函数本体实际上不需要有任何操作,因此效率更高。借用《Effective C++》中的图片说明一下:

想看具体的更加详细解释可以移步详细了解初始化列表构造方式为什么更通用

另外:如果想要使用成员初始化方法写无参数的构造函数的话,可以通过以下的方式实现:

 

最后,说明一下注意事项。

使用成员初始化列表方法的时候需要注意:在初始化的时候需要按照声明的顺序进行初始化,比如你的类定义为:

template <typename Type>
class testClass {
public:
	// 构造函数 
	testClass(Type key1, Type key2);
	
	// 参数
	Type m_value1;
	Type m_value2;
};

template <typename Type>
testClass<Type>::testClass(Type key1, Type key2):m_value1(key1),m_value2(key2){}

定义的时候有两个参数,声明的顺序是m_value1, m_value2,那么在通过成员初始化列表的时候也应该按照这个顺序,先给m_value1赋值,再给m_value2赋值。

在C语言中,结构体的构造函数并不像C++一样有专门的语法来定义。在C中,我们通常使用以下两种方式来实现结构体的构造函数: 1. 默认构造函数:在定义结构体时,可以不显式地写出构造函数,C语言会自动为结构体生成一个默认构造函数。例如,在定义结构体Node时,可以使用Node(){}的形式定义一个默认构造函数。这个默认构造函数在创建结构体对象时会被调用,用来初始化结构体的成员变量。 2. 显式构造函数:在C语言中,我们可以通过定义一个外部的函数来模拟结构体的构造函数。例如,在上面的例子中,我们可以定义一个函数来初始化Node结构体的成员变量,并返回一个已经初始化好的Node对象。例如,可以定义一个函数Node* createNode(int val, Node* next)来创建一个Node对象,并将val和next参数赋值给Node对象的成员变量。 总而言之,在C语言中,我们可以通过默认构造函数或者显式构造函数初始化结构体的成员变量。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【C++】结构体构造函数和实例化详解-打包解决你的所有困惑(●‘◡‘●)](https://blog.csdn.net/icecreamTong/article/details/130627646)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++结构体作为函数参数传参的实例代码](https://download.csdn.net/download/weixin_38699302/14908236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值