Effective C++ 条款05_不止于此

了解C++ 默默编写并调用哪些函数

先来看看一个空类

class Empty{ ... };  //  空类

当有对象被创建出来并调用这些函数的时候 C++ 就会产出下面这些函数 :

class Empty {
public:
	Empty(){...};   //默认(default )构造函数
	Empty(const Empty& params){...};  // 拷贝(copy)构造函数
	~Empty(){...};        //析构函数
	
	Empty& operator=(const Empty& params){...};   // copy assignment 操作符
};

下面创建类的对象以及使用:

Empty e1;   // 调用默认构造函数和析构函数
Empty e2(e1);// 调用copy构造函数
e2 = e1;    // 调用 copy assignment 操作符
  • copy 构造函数和 copy assignment 操作符,编译器创建的版本只会单纯地将来源对象的每一个 non-static 成员变量拷贝到目标对象。

下面来看看 copy 构造函数的用法
直接上代码:

#include<iostream>

template <typename T>
class Adg {
	std::string _name;
	T _value;
public:
	Adg(const char* name, const T& value);  	// 声明构造函数
	Adg(const std::string& name, const T& value);	// 构造函数重载
};
template <typename T>
Adg<T>::Adg(const char* name, const T& value) {    // 定义构造函数
	_name = name;
	_value = value;
}
template <typename T>
Adg<T>::Adg(const std::string& name, const T& value) {
	_name = name;
	_value = value;
}
int main() {
	Adg<int> no1("gwww", 2);
	Adg<int> no2(no1);					// 调用 copy 构造函数
	return 0;
}

由于已经显式声明了构造函数,系统不再生成默认构造函数。
下面来看创建类的对象

Adg<int> no1("gwww", 2);
Adg<int> no2(no1);					// 调用 copy 构造函数
  • 由于 _name 的类型为 string, 所以第二条语句执行调用的是第二个为 string 类型的构造函数,并以 no1._name 和 no1._value 为实参进行 copy 构造完成初始化。
    若进行如下操作:
Adg<int> no3 = no1;		//调用 copy assignment 操作符

编译器为 Adg所生出的 copy assignment 操作符行为和 copy 构造函数的行为一样。
但有时候编译器会拒绝为 class 生出 operator=。
看代码

#include<iostream>

template <typename T>
class Adg {
	std::string& _name; 			//改为了引用类型
	const T _value;					//加了const
public:
	Adg(std::string& name, const T& value);	// 构造函数重载
	// 下面创建对象使用变量初始化 string 类型变量, 所以去掉了const
	// 如果加上 const,两种初始化方式都可以
};

template <typename T>
Adg<T>::Adg(std::string& name, const T& value) : _name(name), _value(value) { }
//上一条款提到了成员变量是const 或者 reference, 他们就一定需要初值,不能被赋值。
//也就是不能写成下面这样
/*
template <typename T>
Adg<T>::Adg(std::string& name, const T& value){ 
 _name = name;
 _value = value;
}
*/
int main() {
	std::string newDog("gwww");
	Adg<int> no1(newDog, 2);
	Adg<int> no2(no1);					// 正确,调用 copy 构造函数
	no2 = no1;							// 错误! 
	return 0;
}

从上面代码可以得出,当 no1._name 指向string对象 no1 时,不能通过 copy assignment 操作符改变 no1._name 所指的对象来指向 no2。不过调用 copy 构造函数不会出现这种情况。
当然,更改 const 成员也是不合法的。

  • 最后请记住:
    编译器可以暗自为 class 创建 default 构造函数、copy 构造函数、copy assignment 操作符,以及析构函数( 如果它们被调用的话)。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值