effective C++读书笔记--【条款05:了解C++默默编写并调用哪些函数】

蓝图

码农没干

    -->编译器代劳

           -->编译器什么时候动手

                      -->编译器的劳动产出的特殊之处

                                   -->编译器的copy assigment的坑

空类

作者提出了一个所谓的“空类”的概念,对于普通码农来讲,空结构体可能更易理解,比如这样子:

struct empty_str {};

没有任何成员的结构体应该就是“空结构体”了,用GCC编译可以发现size是0,用G++编译发现size是1,不纠结这个0和1了,和主题无关。

那么对应的C++的空类大概也是这样子吗?

class EmptyClass{};

G++编译,计算size,这个所谓的“空类”size为1。

作者说:

编译之前,在代码文件里这是一个空类;

编译之后,这个在目标文件里就不是一个纯粹的空类,用作者的话说:在编译的时候被C++处理过了。

虽然我们在代码层面声明了我们以为的“空类”,但是在编译的时候C++(也就是编译器)自动的给声明了“编译器版本”(对应码农的自己实现版本)的(而且是public且inline的):

  • copy构造函数;
  • default构造函数;
  • copy assignment操作符;
  • 析构函数

编译器创建这四个函数的时机

码农不声明,编译器给声明,但是这仅仅是声明,并不保证这些函数真的就会被创建。因为C/C++仅仅声明一个函数,只要不调用,不定义函数也是可以的,比如这样是完全没问题的:

int fakeFunc(int a);
int main()
{
    cout << "do not define fakeFunc" <<endl;
    return 0;
}

或者这样也是可以的,只要保证不会实际调用:

class TstClas {
public:
    int a;
    //只有声明,不定义,如果调用,在连接阶段会报错
    TstClas(const TstClas&);
    TstClas& operator=(const TstClas&);
}

int main()
{
    TstClas theTst;
    theTst.a = 1;
    return 0;
}

那编译器什么时候创建这些函数呢,答案是当“编译器需要的时候”,比如编译在编译的时候,发现某一句代码需要调用所谓的“空类”的copy构造函数,但码农又没有定义copy构造函数,于是编译器赶紧自己写了一个;发现需要调用构造函数确没有定义构造函数,编译器赶紧就摸出了一个default构造函数。

Empty_class e1;     //编译器:没有构造函数和析构函数哎,我自己弄一个吧
Empty_class e2(e1); //编译器:copy构造函数也得自己弄
e2=e1;               //编译器:不省心 copy assignment操作符也得DIY了

编译器实现的这四个函数的特点

default构造和析构函数:调用base classes和non-static成员变量的构造函数和析构函数;

析构函数:编译器默认产出non-virtual,除非base class自身声明有virtual析构函数;

copy构造函数和copy assignment操作符:单纯的将来源对象的每个non-static成员变量复制到目标对象的对应成员变量中;

copy构造函数和copy assigment操作符所谓的“copy”

这里的“copy”一般解释是“将来源对象的每个non-static成员变量复制到目标对象的对应成员变量中”,但是对于不同的成员情况,有两种处理方式:

成员是具有copy构造函数的标准类或码农自己实现的类:调用成员的copy构造函数;

成员是内置类型如int,char *p等:直接按照bits复制;

显然,是浅copy。

copy assigment操作符的两个大坑

如果码农自己没有实现copy assigment操作符,编译器给提供一个,但是存在两个大坑导致编译器“提供copy assigment操作符”失败“表现出来就是编译不过”。

坑一:class A内含reference成员和const成员:必然的,copy不了,reference成员和const成员不允许改变初始值;

坑二:class A的base class中实现了一个private copy assigment操作符:class A的copy assigment发现无法调用bass class的copy assigment,两手一摊:“这事儿我干不了”;

猜你喜欢

转载自blog.csdn.net/haolianglh/article/details/88931863