C++在空类下默默编写并调用了哪些函数

什么时候empty class不再是个空类呢?当C++处理之后。如果没声明,编译器就会给它声明一个copy构造函数、一个copy assignment操作符和一个析构函数。此外如果没有声明任何构造函数,编译器也会给你声明一个default构造函数。所有这些函数都是public且inline。因此,如果你写下:

class Empty 
{
};

这就好像你写下这样的代码:

class Empty 
{
public:
	Empty() {}								// default构造函数
	Empty(const Empty& rhs) {}				// copy构造函数
	~Empty() {}								// 析构函数
	Empty& operator=(const Empty& rhs) {}	// copy assignment操作符
};

惟有当这些函数被需要,它们才会被编译器创建出来。程序中需要它们是很平常的事。下面代码造成上述每一个函数被编译器产出:

Empty e1;				// default构造函数
						// 析构函数
Empty e2(e1);			// copy构造函数
e2 = e1;				// copy assignment操作符

• default构造函数和析构函数

default构造函数和析构函数主要是给编译器一个地方用来放置“藏身幕后”的代码,像是调用base classes和non-static成员变量的构造函数和析构函数。注意,编译器产生的析构函数是个non-virtual,除非这个class的base class自身声明有virtual析构函数

• copy构造函数和copy assignment操作符

copy构造函数和copy assignment操作符,编译器创建的版本只是单纯地将来源对象的每一个non-static成员变量拷贝到目标对象。考虑一个NamedObject template,它允许你将一个个名称和类型为T的对象产生关联:

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

由于其中声明了一个构造函数,编译器于是不再为它创建default构造函数。这很重要,意味如果你用心设计一个class,其构造函数要求实参,你就无须担心编译器会毫无挂虑地为你添加一个无实参构造函数(即default构造函数)而遮盖掉你的版本。
NamedObject既没有声明copy构造函数,也没有声明copy assignment操作符,所以编译器会为它创建那些函数。现在,看看copy构造函数的用法:

NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1);							// 调用copy构造函数

编译器生成的copy构造函数必须以no1.nameValue和vo1.objectValue为初值设定no2.nameValue和no2.objectValue。两者之中,nameValue的类型是string,而标准string有个copy构造函数,所以no2.nameValue的初始化方式是调用string的copy构造函数并以no1.nameValue为实参。另一个成员NamedObject::objectValue的类型是int,那是个内置类型,所以no2.objectValue会以“拷贝no1.objectValue内的每一个bits”来完成初始化。
编译器为NamedObject所生的copy assignment操作符,其行为基本上与copy构造函数如出一辙,但一般而言只有当代码合法且有适当机会证明它有意义。万一两个条件有一个不符合,编译器会拒绝为class生出operator=。

• 总结

编译器可以暗自为class创建default构造函数、copy构造函数、copy assignment操作符,以及析构函数。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章