• C++ 对象模型学习记录(1) 第2章 构造函数语义学


    1. 

    #include <iostream>

    using namespace std;

    class Foo
    {
    public:
    Foo(),Foo(
    int);
    };
    //这里被合成的Bar default 构造函数内含有member
    //object,foo拥有default constructor,所以会初始化Bar::foo()
    //但是初始化str 的责任是程序员的,即编译器不会初始化str

    class Bar
    {
    public:
    Foo foo;
    //内含
    char *str;
    };
    void foo_bar()
    {
    Bar bar;

    }
    int main()
    {
    cout
    << "Hello world!" << endl;
    return 0;
    }

      上述代码中的bar 可能会被转化为

    Bar::Bar()

    {

         //伪码

          foo.Foo()::Foo()

    }

    而被合成的default constructor 只满足编译器的需要,不满足程序的需要,要是程序正确,还必须将str初始化

    Bar :: Bar(){str = 0;} ,有了这个自定义的构造函数,编译器没法合成第2个了,这时,编译器采取:

    “如果class A 内含有一个或者一个以上的member object” ,那么class A 的每一个constructor都必须调用每一个member classes 的default constructor

    如果有多个 member object,编译器以声明他们的顺序完成初始化

    2   有4种情况,编译器会为 未声明的constructor 的class合成一个default 构造函数

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

                如何避免合成多个default 构造函数? 编译器使用inline函数。

               实际上,default constructor,default destructor,assignment copy operator都是以内联的方式完成的,内联函数是静态链接的

       (2)带有 default 构造函数的 base class 基类

               如果没有任何constructor的class继承自一个“带有构造函数的类”,那个这个drived class子类的默认构造函数会被视为一个nontrivial,被合成出来,如果在子类中定义了多个构造函数,但是没有一个使用base类 的 default构造函数,编译器会扩展子类的每一个构造函数

        (3) 带有virtual 函数的 class 

               class 声明为(或者继承自)一个virtual 函数

              class派生自一个继承串链,其中有一个或者多个virtual 函数

        (4) 带有一个虚基类的class 

      两种误解

        1. 任何class ,如果没有定义默认构造函数,编译器会自动创建一个 

        2. 编译器合成出来的default构造函数会明确的设定class内的每一个data member的默认值

    编译器只会设置对编译必须的值,而其他的默认值必须由程序员自己初始化

    #include <iostream>
    using namespace std;
    class String
    {
    //类中没有显示的提供copy构造函数
    public:
    String(
    string name)
    {
    str
    = name;
    }
    string getStr()
    {
    return str;
    }
    private :
    string str;
    };

    int main()
    {
    String noun(
    "book");
    String verb
    = noun;
    cout
    << verb.getStr() << endl;
    return 0;
    }

      

    3.  copy 构造函数建构的3种情况

         1. 对一个类做明确的初始化操作

         2. 当作函数的形参时

         3. 当一个函数的返回值(回传一个对象)

    另外,如果么有显示的实现copy构造函数,编译器使用所谓的default memberwise initializator 手法,将一个内建的data member从一个object拷贝到另一个object中,不过不会拷贝member class object,对他们则是递归的使用default memberwise initializator 手法

    一个错误的认识:

    对于未定义拷贝构造函数的类,编译器会自动实现一个copy拷贝构造函数 

    c ++ Standard 将copy 构造函数分为 nontrivial 和 trivial,只有nontrivial的才会被合成到程序之中

    而是不是trivial的,取决于 class 是不是展现出 bitwise copy semantics(位逐次拷贝)

    4 .什么时候class不展现位逐次拷贝

          1. 当class内含有一个member class object,而这个member class 内有一个默认的copy 构造函数

          2. 当class 继承自 一个base class,而bese class 有copy构造函数

         3. 当一个类声明了多个virtual 函数

         4. 当class派生自一个继承串链,其中一个或者多个virtual base class 

  • 相关阅读:
    换个角度思考问题
    云南印象
    子网掩码划分实例
    子网掩码划分工具下载
    实景地图
    AutoCAD图像输出(输出图像)技巧
    两种消费观念
    子网掩码划分计算方法及实例
    C/C++从入门到高手所有必备PDF书籍收藏
    WINCE6.0添加特定的软件键盘
  • 原文地址:https://www.cnblogs.com/hitwtx/p/2160012.html
Copyright © 2020-2023  润新知