条款05:了解C++默默编写并调用了哪些函数

对于一个empty class(空类),编译器就会为它声明(编译器版本的)一个copy构造函数,一个copy assignment操作符和一个析构函数,此外你没有声明任何构造函数,编译器也会为你声明一个default构造函数。

如下所示:

//当你写下如下的代码:
class Empty{};

//就像如下的代码一样:
class Empty
{
public:
	Empty{...};							//default构造函数
	Empty(const Empty& rhs){...}		//copy构造函数
	~Empty{...};						//析构函数,是否为虚见稍后说明
	Empty& operator = (const Empty& rhs) {...};//copy assignment操作符
};

唯有当这些函数被需要(调用),它们才会被编译器创建出来。

对于这几个函数而言作用:default构造和析构函数主要给编译器一个地方来放置“藏身幕后”的代码,像是调用base classes和non-static成员变量的构造函数和析构函数。至于copy构造函数和copy assignment操作符,编译器创建的版本只是单纯的将源对象的每一个non-static成员变量拷贝到目标对象。

编译器生成的copy assignment操作符,其行为基本上和copy构造函数如出一辙,但一般而言只有当生成的代码合法且有适当机会证明他有意义,其表现才会如我们所说的。万一条件不符合,编译器会拒绝为class生成operator=。

特殊的情况,如下NamedObject定义如下,nameValue是个reference to string,objectValue是个const T:

template<class T>
class NamedOjbect
{
public:
	NamedOjbect(std::string& name,const T& value);
	...
private:
	std::string& nameValue;
	const T objectValue;
};

std::string newDog("Persephone");
std::string oldDog("Satch");
NamedOjbect<int> p(newDog,2);
NamedOjbect<int> s(oldDog,36);

p = s;//现在p的成员变量该发生什么事

赋值之前,不论p.nameValue和s.nameValue都是指向string对象(不是同一个),赋值动作该如何影响p.nameValue?因为C++不允许“让一个reference指向不同对象”。对面const成员也是如此,更改const成员时不合法的。

面对这问题,C++编译器拒绝为其合成copy assignment,你必须自己定义copy assignment。最后还有一种特殊情况:如果某个base classes将copy assignment操作符声明为private,编译器也会拒绝为其derived classes生成一个copy assignment操作符,毕竟编译器为derived classes所生成的copy assignment操作符想象中可以处理base class成分。

总结

  • 编译器可以暗自为class创建default构造函数、copy构造函数、copy assignment操作符,以及析构函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值