在头文件中初始化类的成员变量是一个好的做法吗?

6

假设我有一个指针,我希望它被初始化为nullptr。哪个选项更好呢?是创建一个构造函数将成员变量设置为nullptr,还是在头文件声明中直接初始化为nullptr?

两者有什么区别吗?后者是否被认为是不良实践?

提前感谢。


默认初始化程序将应用于每个构造函数,因此如果您向类中添加新的构造函数,则无需检查每个成员。您还可以在构造函数中更改默认初始化,这将覆盖该值。我会始终使用默认初始化而不是构造函数初始化,首先因为您可以确保它适用于每个构造函数,第二(在我看来)可读性更好。 - RoQuOTriX
1
我认为唯一可能的不良实践就是在第一时间使用指针。如果使用情况确实需要指针,则应该使用智能指针,例如std::unique_ptr,其默认构造函数将其初始化为“null”。 - Some programmer dude
类似问题:https://dev59.com/eGgu5IYBdhLWcg3wFDNr - IWonderWhatThisAPIDoes
2个回答

6
在类体中初始化成员变量和在构造函数的成员初始化列表中进行初始化是完全等价的。(但如果两个地方都提供了初始化程序,则成员初始化列表将覆盖类体中的初始化程序。)
尽可能在类体中进行初始化是一个好习惯,因为它更少出错(如果您忘记初始化新添加的成员变量,您会立即注意到;请参见DRY)。

为什么如果后者能够覆盖前者,它们就完全等价呢?如果它们是等价的,我会期望使用两种方式分配不同的值会导致未定义行为或其他问题。 - Enlico
1
@Enlico 我认为他的意思是,如果你选择其中一种方式,结果是相同的。他没有提到同时执行两种方式的情况。 - RoQuOTriX
1
@Enlico,RoQuOTriX所说的没错,但我进行了编辑以使它更加清晰。 - HolyBlackCat
顺便提一下,这里并没有完全等价。在类体中,您不必拥有构造函数,因此类可能是聚合的,您可能没有用户提供的构造函数等等。 - Jarod42

5
如果我正确理解了您的问题,那么这个链接应该会为您提供一些信息:CPPCoreGuidelines

C.45: Don't define a default constructor that only initializes data members; use in-class member initializers instead

Reason

Using in-class member initializers lets the compiler generate the function for you. The compiler-generated function can be more efficient.

Example, bad

class X1 { // BAD: doesn't use member initializers

    string s;
    int i;
public:
    X1() :s{"default"}, i{1} { }
    // ...
};

Example

class X2 {
    string s = "default";
    int i = 1;
public:
    // use compiler-generated default constructor
    // ...
};

Enforcement

(Simple) A default constructor should do more than just initialize member variables with constants.


请不要仅贴链接作为答案,至少引用所参考的章节。 - Quimby
4
好的,抱歉我之前没有想到需要添加链接,因为链接直接导向了该部分内容,我会编辑我的信息。 - GeorgeDuckman
4
没问题 :) 有时链接页面会被移动,如果多年后有人偶然发现你的答案但发现链接已经失效,那会很令人沮丧。因此最好在这里至少包含一些信息,但同时保留链接。 - Quimby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接