为非对象使用成员初始化列表是不是很糟糕?

时间:2015-11-06 03:19:28

标签: c++ initializer-list

由于我只是在某些情况下必须使用初始化列表,因此我习惯于将所有内容放在初始化列表中,而构造函数只能用于设置成员的值。

就像我在这里所做的那样:

template <typename generic>
class setsPool
{
    protected:

    set<generic> *pool;
    size_t maxSets;
    generic maximumValue, minimumValue;

    public:

    setsPool() = delete;

    explicit setsPool( size_t maxSets ) :
        pool(new set<generic>[maxSets]), maxSets(maxSets), 
        maximumValue(0), minimumValue(0) {}

    setsPool( size_t maxSets, generic minimumValue, generic maximumValue ) :
        pool(new set<generic>[maxSets]), maxSets(maxSets), 
        minimumValue(minimumValue), maximumValue(maximumValue) {}

    // ...
};

而不是这样做:

template <typename generic>
class setsPool
{
    // ... same stuff

    public:

    setsPool() = delete;

    explicit setsPool( size_t maxSets )
    {
        this->pool = new set<generic>[maxSets]);
        this->maxSets = maxSets; 
        this->maximumValue = minimumValue = 0;
    }

    setsPool( size_t maxSets, generic minimumValue, generic maximumValue )
    {
        this->pool = new set<generic>[maxSets]);
        this->maxSets = maxSets;  
        this->maximumValue = maximumValue;
        this->minimumValue = minimumValue;
    }

    // ...
};

以这个真正的代码为例,我想知道这样做是否有任何缺点(当我没有必须时使用初始化列表)我在这里找到的关于初始化列表的问题似乎并不清楚它是否错误地将其用于非必要情况

  • 因此,我的代码可以效率低吗?
  • 是否配置某种不良做法
  • 我有什么理由骂自己编写这样的代码吗?

2 个答案:

答案 0 :(得分:3)

使用成员(初始化程序)列表(没有&#34;成员&#34;,初始化程序列表引用different concept introduced in C++11)通常被认为是我所知道的更好。没有它,我相信它会在构造函数体中替换它们之前默认构造成员(可能取决于编译器/优化级别)。

作为支持,我指向MSDN

  

会员名单

     
    

使用成员初始化列表从构造函数参数初始化类成员。此方法使用直接初始化,这比在构造函数体内使用赋值运算符更有效。

  

cppreference上(强调补充):

  

在构成构造函数体的复合语句开始执行之前,完成所有直接碱基,虚拟碱基和非静态数据成员的初始化。 成员初始化列表是可以指定这些对象的非默认初始化的地方。对于无法进行默认初始化的成员,例如引用成员和const限定类型,必须指定成员初始值设定项。

这意味着构造函数体中的任何赋值都是重新分配已经(默认)构造的成员。

正如Neil所提到的,对于POD类型,如果未在成员初始化列表中指定,则它们不是默认构造的(例如,设置为0)。因此,如果仅在构造函数体中设置它们,则不会进行冗余初始化,但是使用成员初始化列表列表也不会花费任何成本。

答案 1 :(得分:2)

对于基本数据类型,如指针,整数和浮点数,它并不重要。分配所有这些集合的成本将使任何差异相形见绌,编译器可以轻松优化代码,因为构建和复制基本数据类型没有副作用。

对于generic类型可能属于的非基本数据类型,效率可能较低,尤其是当它们具有大量默认构造函数时。这是因为,如果您不使用初始化列表,则使用默认构造函数创建对象,然后将为其分配新值,可能会浪费默认构造函数所做的工作。

除非有特殊原因,否则我宁愿始终使用初始化列表,以防它更有效。