定义一个空类时,C++到底默默编写了哪些函数?

来源:互联网 发布:mac ai 崩溃 文件恢复 编辑:程序博客网 时间:2024/06/05 10:57

今天看了一本很经典的书籍《Effective C++》中的条款5,感觉书中说得有点混乱,故在此整理一下,并和大家分享一下自己的学习。好,现在开始吧。这个条款可以总结为三个问题:

问题1:当我们定义一个空类的时候,C++编译器会为我们编写哪些函数呢?

问题2:这些默认函数都做了什么工作呢?

问题3:如果要对一个含有“reference成员”的类进行赋值操作,可以依赖编译器生成的赋值重构函数(operator=)吗?

问题1:当我们定义一个空类的时候,C++到底会默默为我们编写哪些函数呢?

例如写了这么一个空类:

class Empty{ };

则,C++会为我们默默地编写了4个函数:一个default构造函数、一个析构函数、一个copy构造函数、一个等号“=”重构函数:

class Empty{

public:

Empty()  {......}                                                                   //default构造函数

Empty(constEmpty& rhs)  {.....}                                   //copy构造函数

~Empty()  {....}                                                                 //析构函数

Empty& operator=(constEmpty& rhs)  {.....}             //等号“=”重构函数(copy assignment 操作符)

};

当然,这些函数只有在被需要的时候,他们才会被编译器创建出来。

Empty e1;                 //default构造函数

                                   //析构函数

Empty e2(e1);         //copy构造函数

e2=e1;                     //等号“=”重构函数

如果,在定义类时,把上面四个函数中的一个或者全部都人工声明了,则编译器不再创建对应的函数。

问题2:这些4个函数都为我们只做了些什么呢?

由编译器创建出来的default构造函数和析构函数,其实只是一个空函数,什么也不做;

至于copy构造函数和等号“=”重构函数,他们只是单纯地将来源对象的每一个non-static成员变量拷贝到目标对象;

对于static成员变量不用拷贝,因为同属于一个类的不同对象的static成员变量都是一样的。

问题3:如果要对一个含有“reference成员”的类进行赋值操作,可以依赖编译器生成的赋值重构函数吗?

如果要对一个含有“reference成员”的类进行赋值操作,是不可以依赖编译器生成的赋值重构函数的,

必须自己定义一个赋值重构函数。

原因,请看下面的代码:

class NameObject{

public:

NameObjec(std::string&name,const int & value)

{

nameValue=name;

objectValue=value;

}//假设并没有声明 等号“=”重构函数

private:

std::string& nameValue;//引用

const int objectValue;

}:

现在考虑下面会发生什么事?

std::string newDog(Tom);

std::string oldDog(Jack);

NameObject p(newDog,2);//定义一个对象

NameObject s(oldDog,4);//再定义一个对象

p=s;//错误    将s对象赋值给p对象

赋值前,p.nameValue和s.nameValue分别是对象newDog和oldDog的引用

那么赋值后,p.nameValue应该是指向s.nameValue所指的那个string对象oldDog吗?当然不是。因为在C++中规定,一个引用与某个变量建立联系后,就不能够再作为其他变量的别名了。所以指定p.nameValue为newDog的引用后,p.nameValue不能够再次指定为oldDog的引用了。

int a1,a2;

int &b=a1;//b为a1的别名

int &b=a2;//错误,因为b已经是变量a1的别名了





0 0
原创粉丝点击