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

C++编译器为未声明任何函数的空类提供默认的构造函数、析构函数、拷贝构造函数和拷贝赋值操作符。然而,含有引用或const成员的类在进行拷贝赋值时需要自定义操作符,因为引用不能重新绑定,const成员也不能修改。如果基类的copyassignment操作符是private的,派生类也无法自动获得此操作符。
摘要由CSDN通过智能技术生成

什么时候empty class不再是个空类了呢?当C++处理它之后。

如果自己没有声明任何函数,C++编译起会为空类声明一个默认的构造函数、析构函数、拷贝构造函数和拷贝复制操作符。所有的这些函数均是public且inline的。

因此,如果你写下:

class Empty { };

这就好像你写下以下代码:

class Empty 
{
public:
	Empty() {...}								// 默认构造函数
	Empty(const Empty& rhs) {...}				// 拷贝构造函数
	~Empty() {...}								// 析构函数,是否该是virtual稍后说明
	Empty& operator=(const Empty& rhs) {...}	// 拷贝复制操作符
	
}

只有当这些函数被调用,它们才会被编译创造出来;如果类中已有构造函数,则无须担心编译器会给生成默认的无参构造函数。
注意:编译器产出的析构函数是个non-virtual。

下面有一个值得思考的比较有意思的问题。

topic1: 如何在一个内含reference的class内支持拷贝赋值操作?

举例:

class NameObject
{
public:
	NameObject(std::string& name, const int& value);
	...
private:
	std::string& nameValue;			// reference
	const int objectValue;			// const
}

考虑下面会发生什么事

std::string newDog("Peter");
std::string oldDog("Satch");

NameObject p(newDog);
NameObject s(oldDog);
p = s;

赋值前,不论p.nameValue和s.nameValue均指向string对象。赋值操作如何影响p.nameValue呢?赋值之后p.nameValue指向s.nameValue 所指的那个string吗?也就说,reference自身可以被改动吗?如果是,那可就开天辟地了,因为C++不允许“让reference改指向不同的对象”。

面对这个难题,C++的响应是拒绝编译那一行赋值语句。如果在一个内含reference的class内支持拷贝赋值操作,需要自己定义copy assignment操作符。

topic2:如何在一个内含const成员的class内支持拷贝赋值操作

对内含const成员的class,编译器的反应也是一样。更改const成员是不合法的,同样需要自己定义copy assignment操作符。

topic3:base class的copy assignment操作符声明为private

如果某个base class将copy assignment操作符声明为private,编译器将拒绝为其derived class生成一个copy assignment操作符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值