zoukankan      html  css  js  c++  java
  • C++ 构造函数初始化列表

    转自:https://www.cnblogs.com/wkfvawl/p/10902220.html

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:

    复制代码
    class A
    {
    public:
        int a;
        float b;
        A(): a(0),b(9.9) {} //构造函数初始化列表
    };
    
    class A
    {
    public:
        int a;
        float b;
        A()   //构造函数内部赋值
        {
            a = 0;
            b = 9.9;
        }
    };
    复制代码

    上面的例子中两个构造函数的效果是一样的。使用初始化列表的构造函数是显示地初始化类的成员;而没有使用初始化列表的构造函数是对类的成员赋值,并没有显示地初始化。

    初始化列表的构造函数和内部赋值的构造函数对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。
    用构造函数的初始化列表来进行初始化,写法方便、简练,尤其当需要初始化的数据成员较多时更显其优越性。对非内置类型成员变量,推荐使用类构造函数初始化列表。
    但有的时候必须用带有初始化列表的构造函数:(1)没有默认构造函数的成员类对象;(2)const成员或引用类型的成员。

           构造函数中有着比我们所看见的还要多的细节,构造函数可以调用其它的构造函数来初始化对象中的基类对象和成员对象的构造函数。
    类的数据成员中的其它类对象,若该成员类型是没有默认构造函数,则必须进行显示初始化,因为编译器会隐式调用成员类型的默认构造函数,而它又没有默认构造函数,则编译器尝试使用默认构造函数将会失败。

    例:

    复制代码
    class A
    {
    public:
        A (int x)
        {
            i = x;    // 无默认构造函数
        }
    private:
        int i;
    };
    class B
    {
    public:
        B(int y)
        {
            j = y;    // error C2512: “A”: 没有合适的默认构造函数可用
        }
    private:
        A a;
        int j;
    };
    int main( )
    {
        B b(5);
        return 0;
    }
    复制代码

    B类数据成员中有一个A类对象a,创建B类对象时,要先创建其成员对象a;A类有一个参数化大的构造函数,则编译器不会提供默认无参数的构造函数,因此a无法创建。

    对成员对象正确的初始化方法是通过显示方式进行,B的构造函数应该写成:

    B(int y, int z) : a(z)
    {
        j = y;
    }
    B b(5,10);

    构造函数初始化列表是初始化常数据成员和引用成员的唯一方式。因为const对象或引用类型只能初始化,不能对他们赋值。

    复制代码
    class A
    {
    public:
        A (int x,int y) : c(x),j(y)     // 构造函数初始化列表
        {
            i = -1;
        }
    private:
        int i;
        const int c;
        int& j;
    };
    int main( )
    {
        int m;
        A a(5,m);
        return 0;
    }
    复制代码

    若不通过初始化列表来对常数据成员和引用成员进行初始化:

    复制代码
    class A
    {
    public:
        A (int x)      // 构造函数初始化列表
        {
            i = -1;
            c = 5;
            j = x;
        }
    private:
        int i;
        const int c;  // error C2758: “A::c”: 必须在构造函数基/成员初始值设定项列表中初始化
        int& j;     // error C2758: “A::j”: 必须在构造函数基/成员初始值设定项列表中初始化
    };
    复制代码

    缺省情况下,在构造函数的被执行前,对象中的所有成员都已经被它们的缺省构造函数初始化了。当类中某个数据成员本身也是一个类对象时,我们应该避免使用赋值操作来对该成员进行初始化:

    复制代码
    class Person
    {
    private:
        string name;
    public:
        Person(string& n)
        {
            name = n;
        }
    }
    复制代码

    虽然这样的构造函数也能达到正确的结果,但这样写效率并不高。当一个Person对象创建时,string类成员对象name先会被缺省构造函数进行初始化,然后在Person类构造函数中,它的值又会因赋值操作而在改变一次。我们可以通过初始化列表来显示地对name进行初始化,这样便将上边的两步(初始化和赋值)合并到一个步骤中了。

    复制代码
    class Person
    {
    private:
        string name;
    public:
        Person(string& n): name(n){}
    }
    复制代码
    诸位正值青春年少,一定恣情放纵,贪恋香艳梅施之情,喜欢风流雅韵之事,洒脱木拘。然而诸位可知,草上露一碰即落,竹上霜一触即溶,此种风情难于长久。
  • 相关阅读:
    vue六十五:vuex-getters和vuex-mapGetters
    vue六十四:vuex-mapStore
    vue六十三:vuex的异步处理
    vue六十二:vuex的同步状态管理和调试工具vue-devtools
    vue六十一:使用vuex管理状态示例
    vue六十:电影院售票项目案例之影院页面和使用Better-Scroll实现拖拉滚动
    vue五十九:电影院售票项目案例之详情页面
    vue五十八:电影院售票项目案例之项目吸顶效果
    ingress 413 Request Entity Too Large
    kubeadm搭建K8S集群
  • 原文地址:https://www.cnblogs.com/shilipojianshen/p/13743346.html
Copyright © 2011-2022 走看看