【问题标题】:C++ Member Initialization ListC++ 成员初始化列表
【发布时间】:2011-12-01 16:13:35
【问题描述】:

请解释如何使用成员初始化列表。 我在.h 文件和.cpp 文件中声明了一个类,如下所示:

class Example
{
private:
    int m_top;
    const int m_size;
    ...
public:
    Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1);
    ...
    ~Example();
};

由于const,我在对象创建时初始化m_size。我应该如何编写构造函数? 我应该重复: m_size(5), m_top(-1),还是可以省略这一步?

Example::Example( int size, int grow_by)
{
... some code here
}

Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}

【问题讨论】:

  • 在定义构造函数时指定初始化列表,而不是在声明时指定。

标签: c++


【解决方案1】:

只是为了澄清一些其他答案中出现的问题......

初始化列表不要求在源文件 (.cpp) 或头文件 (.h) 中。 事实上,编译器并不区分这两种类型的文件。重要的区别在于构造函数的declaration 和它的定义。初始化列表随定义而不是声明。
通常,声明在头文件中,定义在源文件中,但是,这不是语言的要求(即它会编译)。 当构造函数为空或短时,在类声明中内联提供构造函数定义并不罕见。在这种情况下,初始化列表将进入类声明中,这可能在头文件中。

MyClass.h

class MyClass
{
public:
    MyClass(int value) : m_value(value)
    {}
private:
    int m_value;
};

【讨论】:

  • 注意:某些框架和语言(如 Qt 的 C++)要求其从 QObject 派生的类和结构使用自己的标头来利用其 Q_OBJECT 宏以正确利用其潜力。
【解决方案2】:

这是初始化列表:

Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}

而且应该只在 cpp 文件中完成。

当您像在示例中的标题中那样执行此操作时,您不会收到错误吗?

【讨论】:

    【解决方案3】:

    成员初始化器列表应该是源文件中定义的一部分。
    将其写入 .cpp 文件中:

    Example ( int size, int grow_by) : m_size(5), m_top(-1)
    {
    
    }
    

    头文件应该只有:

    Example ( int size, int grow_by = 1 );
    

    头文件只声明构造函数,成员初始化器列表不是声明的一部分。

    【讨论】:

    • 即初始化列表只进入构造函数定义。
    • @CatPlusPlus:哦,在您发表评论之前编辑它有点晚了:P
    • 我认为= 1默认参数应该只在标题中,而不是cpp文件中。
    • @MooingDuck:正确!啊错误cntrl + ccntrl + v 坏习惯:P!
    • 此外,数据成员按照声明的顺序进行初始化,因此最好以相同的方式对初始化列表进行排序以保持一致。在您的示例中,这将是: m_top(-1), m_size(5)。参见 Meyers 的Effective C++,第 4 项。
    【解决方案4】:

    除了其他答案之外,关于初始化列表,最重要的一件事是, the order of initialization is decided in the order in which the data members are declared, not the the order in which you have initialized the data members using initialization list

    考虑这个例子(你的):

    class Example { private: int m_top; const int m_size; ... public: Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1){} /* Though size is initialized with a value first But it is m_top variable that is assigned value -1 before m_size is assigned value 5 */ ... ~Example(){} }; 如果不了解上述情况,可能会造成非常严重的影响。

    【讨论】:

    • 许多编译器会警告初始化顺序,如果看起来可能存在可能导致问题的歧义。如果未启用此类警告,则应启用并注意此类警告。
    • 是的,但仍然值得知道警告的真正含义:)
    【解决方案5】:

    在 C++11 中,您可以使用 non-static data member initialization。如果您有多个构造函数需要成员变量的公共值,这将特别有用。

    class Example
    {
    private:
        int m_top = -1;
        const int m_size = 5;
        ...
    public:
        Example ( int size, int grow_by = 1 );
        ...
        ~Example();
    };
    
    ...
    
    Example::Example( int size, int grow_by )
    {
        ... some code here
    }
    

    如果需要,您可以覆盖构造函数中的值。

    【讨论】:

      【解决方案6】:

      你不能在 header 和 cpp 中都有初始化列表。该列表应该在哪个文件中定义了您的构造函数。此外,即使它是空的,也必须包含构造函数的主体。

      附带说明,您应该只在函数原型中而不是在定义中指定默认参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-14
        • 2019-09-10
        • 1970-01-01
        • 2017-03-30
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        相关资源
        最近更新 更多