c++的编译器是非常智能的!当你声明一个空类empty class,如果你的代码有用到这个empty class时,编译器会默默的为你编写一些基本的函数。那么究竟编译器自己添加的函数都有哪些呢?构造函数,析构函数,一个copy构造函数和一个copy assignment操作符。举个例子来说明一下,如果你写下:
class empty{};
就好像你写下这样的代码:
class Empty
{
public:
Empty(){ ... } //default 构造函数
~Empty(){ .... } //析构函数
Empty(const Empty & rhs) { ... } //copy 构造函数
Empty & operator=(const Empty & rhs) { ... } //copy assignment 操作符
/* data */
};
不过需要有一点值得注意: 只有当这些函数被调用的时候,他们才会被编译器创建出来。
如果你不想用默认的构造函数,那么你可以自己手工创建构造函数,这是就会遮盖掉默认构造函数,不再允许调用默认的构造函数。
copy构造函数和copy assignment操作符都是属于copy操作,copy操作会将需要拷贝的参数分别调用每个参数的base class的copy方法进行copy。如
template<typename T>
class NameObject
{
public:
NameObject(const char * name, const T& value);
NameObject(const std::string & name, const T& value);
~NameObject();
....
/* data */
private:
std::string nameValue;
T objectValue;
};
NameObject<int> no1("test string", 2);
NameObject<int> no2(no1);
此时no2.nameValue以no1.nameValue为实参,nameValue是string类型,所以会no2.nameValue会调用string的copy函数进行赋值
no2.objectValue是int类型,会直接拷贝no1.objectValue的每个bits进行赋值。
但是并不是所有情况编译器都可以生成operator=的方法,不满足的情况主要包括下面两种:
- 待赋值的成员变量中包含引用
- 待赋值的成员变量中包含const变量
聪明的你想必已经想到了!对了, c++并不允许“让reference改指向不同对象”。同时,对一个const成员进行赋值也是个bad idea!
如果你打算在一个含有reference成员的class内支持赋值操作符,你必须自己定义copy assignment操作符。
请记住:
编译器可以暗自为class创建default构造函数,copy构造函数,copy assignment操作符,以及析构函数。