6

Let's say I have a pointer and I want it to be initialized to nullptr. Which option would be better, to create a constructor that sets that member variable to nullptr or just initialize it in the declaration on the header file to nullptr.

Is there any differences at all? Is the latter considered bad practice?

Thanks in advance.

elmarki
  • 175
  • 1
  • 4
  • Default initializers are getting applied to EVERY constructor, so if you add a new constructor to the class you don't need to check every member. You can also change the default initialization in the constructor which overrides the value. I would always use default initialization instead of constructor initialization, first because you can be sure that it happens for every constructor and second (IMO) it the readability is better – RoQuOTriX Mar 23 '21 at 07:09
  • 1
    I would argue that the only possible bad practice is the use of pointers in the first place. And if the use-case really requires a pointer then use a *smart* pointer like [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr), whose default-constructor will initialize it to be "null". – Some programmer dude Mar 23 '21 at 07:15
  • Similar question: https://stackoverflow.com/questions/11594846/default-member-values-best-practice – IWonderWhatThisAPIDoes Mar 23 '21 at 07:16

2 Answers2

6

Initializing a member in the class body is completely equivalent to doing it in the member initializer list in the construcor. (But if you provide initializers in both places, member-init-list overrides initializers in class body.)

Initializing in the class body whenever possible is a good practice, because it's less error prone (you'll immediately notice if you forget to initialize a newly added member; see DRY).

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • Why is it completely equivalent, if the latter is able to override the former? If they were equivalent I would expect that using both way assigning different values would UB or something. – Enlico Mar 23 '21 at 07:12
  • 1
    @Enlico I think he meant that if you do one or the other one the result is the same. He did not say anything about doing both at the same time – RoQuOTriX Mar 23 '21 at 07:14
  • 1
    @Enlico What RoQuOTriX said, but I edited to make it more clear. – HolyBlackCat Mar 23 '21 at 07:16
  • There are not entirely equivalent BTW: in the class body, you don't have to have constructor, and so class might be aggregate, you might have no user provided constructor, and so on. – Jarod42 Mar 23 '21 at 08:50
5

If I understood your question correctly, this link should give you some information : 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.

  • Please do not post link-only answers, at least cite the section you are referring to. – Quimby Mar 23 '21 at 07:43
  • 4
    Ok, sorry I didn't think it was necessary since the link leads directly to the section, I will edit my message – GeorgeDuckman Mar 23 '21 at 07:53
  • 4
    No worries :) Sometimes linked pages get moved around and it will be frustrating if years from now, someone will stumble upon your answer only to find a dead link. So it is better to at least include some information here. But keep the link as well. – Quimby Mar 23 '21 at 07:56