• Constructor


    C++ Annotated Reference Manual中说“default Constructor 在需要的时候被编译器产生出来”,其关键字就是“需要的时候”,是谁需要呢?创建出来干什么事呢?

    class Foo {

    public:

    int val;

    Foo *pNext;

    };

    void foo_bar()

    {

    Foo bar;

    if(bar.val || bar.pnext)

    // do something;

    }                                                                                                                                                                                                                                                                                                                

    在这个例子中,正确的语义是要求Foo有个default Constructor,可以将它的两个members初始化为0。但这段代码并不满足ARM中说的“在需要的时候”,其差别就在于一个是程序的需要,一个是编译器的需要。如果程序有需要,那是程序员的责任;只有编译器有需要时,编译器才会产生 default Constructor。因此,这个例子中,程序员必须explicitly 创建一个Constructor,并将val和pNext初始化。

    对于class X,如果没有任何user-defined constructor,那么就会有一个default Constructor被implicitly 声明出来,一个被implicitly声明出来的default Constructor将是一个trivial的Constructor。并不是所有的implicitly default Constructor都是trivial的。有四种情况下的default Constructor是nontrivial的:

    1. 带有 default 构造函数的 Member Class Object

    如果一个class没有任何的constructor,但是它内含有一个member object,而这个成员object有默认的构造函数,那么这个类的implicit的default constructor就是nontrivial的,编译器会合成一个default 构造函数,不过这个默认构造函数仅仅在需要的时候合成

    如何避免编译器的多个模块合成多个default 构造函数? 编译器是使用inline函数做的:实际上,default constructor,default destructor,assignment copy operator都是以内联的方式完成的,内联函数是静态链接的。

    class Foo

    {

    public:

    Foo(),Foo(int);

    };

    class Bar {

    public:

    Foo foo;

    char * str;

    };

    在这个例子中,Bar中有一个类型为Foo的member,因此Bar的implicit default Constructor就是nontrivial的,在其中,需要调用Foo的default Constructor。但Bar中str并不会被初始化,引起它是程序员的责任。

    1. 带有 default 构造函数的 base class 基类

    这跟上面的情形类似。

    1. 带有virtual 函数的 class [virtual函数可以是继承的或者自己声明的]

    为了支持virtual function,下面两个扩张操作会在编译期间发生:

    生成一个virtual function table(vtbl),其中放置class的virtual functions地址;

    生成一个pointer member(vptr),内含相关的class vtbl的地址;

    对于那些没有声明任何Constructor的class,编译器会为它们合成一个default Constructor,以便正确地初始化每一个class object的vptr。

    1. 继承自一个继承串链,其中有一个或者多个virtual base class

    《看完第一章后需要补充》

    两种误解
        1. 任何class ,如果没有定义默认构造函数,编译器会自动创建一个
        2. 编译器合成出来的default构造函数会明确的设定class内的每一个data member的默认值

  • 相关阅读:
    Linux 查看内存状态
    Linux sar工具安装使用
    DNS ARP地址解析原理
    TCP/UDP 端口
    TCP/IP 传输原理
    Window vagrant 安装部署【转】
    Window7下vagrant的部署
    Ubuntu下访问SSH
    使用 Vagrant 打造跨平台开发环境
    Vagrant入门[转]
  • 原文地址:https://www.cnblogs.com/whyandinside/p/2497234.html
Copyright © 2020-2023  润新知