effect C++ 了解C++默默编写并调用哪些函数

empty class

编译器会对一个空类自动声明一个copy构造函数,一个copy assignment操作符和一个析构函数。如果没有声明任何构造函数,编译器也会声明一个default构造函数,所有这些函数都是public且inline

class Empty{}
相当于

class Empty{
public:
  Empty();                        //default 构造
  Empty(cosnt Empty&rhs){...}     // copy析构 
  ~Empty(){...}                  
  Empty&operator=(cosnt Empty& rhs){...}
}

唯有当这些函数被调用,才会被编译出来
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 操作符 ,编译器创建的版本只是单纯地将来源对象的每一个non-static 成员变量拷贝到目标对象。

考虑一个NamedObject template,它允许你将一个个名称和类型为T的对象产生关联:

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

由于其中声明了一个构造函数,编译器于是不再为它创建default构造函数。

copy assignment操作符

NamedObject<int>("Smallest Prime Number",2);
NamedObject<int>no2(no1);         //调用copy函数
编译器生成的copy函数必须以no1.nameValue 和 no1.objectValue为初值设定no2.nameValue和no2.object. nameValue的类型是string,no2.nameValue调用string的copy构造函数并以no1.nameValue为实参。NameObject<int>::objectValue的类型是int,那是个内置类型,所以no2.objectValue会以“拷贝no1.objectValue内的每一个bits”来完成初始化


编译器为NamedObject<int>所生的copy assignment操作符,其行为基本上与copy构造函数如出一辙。若有条件不符合,编译器会拒绝为class生成operator=

template<class T>
class NameObject{
public:
//以下构造函数如今不再接受一个const,
//因为nameValue如今是个
reference-to-non-const string。
//先前那个char*构造函数已经过去了,因为必须有个sting可提供指涉。
 NameObject(std::string &name,const T&value);
..... //未声明operator=
private:
std::string&nameValue; 
const T objectValue;
}
如果发生如下操作

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

p=s;


赋值之前,不论p.nameValue 和 s.nameValue指向的string对象(肯定不是同一个),赋值如何影响p.nameValue? 

c++并不允许让reference改指向不同对象,所以c++会拒绝编译那一行赋值动作。必须自己定义copy assignment。 面对const成员,编译器也一样。

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



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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值