Pedro V. G.
Pedro V. G.

Reputation: 353

Is it bad to use member initializer list for non-objects?

Since I just Have to use initializer list in some cases, I got the habit of just putting everything on the initializer list WHEN the constructor would only serve to set members' values.

Like what I did here:

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) {}

    // ...
};

Instead of doing this:

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;
    }

    // ...
};

Given this real code as an example, I wanted to know if there are any cons on doing so (using initializer list when I don't really Have to) and the questions on initializer lists I've found here don't seem to make it clear if its wrong to use it on not-necessary cases.

Upvotes: 3

Views: 872

Answers (2)

ShadowRanger
ShadowRanger

Reputation: 155418

Using member (initializer) lists (w/o "member", initializer list refers to a different concept introduced in C++11) is usually considered better to my knowledge. Without it, I believe it ends up default constructing the members before you replace them in the constructor body (may depend on compiler/optimization level).

As support, I point you to MSDN:

Member Lists

Initialize class members from constructor arguments by using a member initializer list. This method uses direct initialization, which is more efficient than using assignment operators inside the constructor body.

And on cppreference (Emphasis added):

Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished. Member initializer list is the place where non-default initialization of these objects can be specified. For members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.

Which implies that any assignment in the constructor body is reassigning already (default) constructed members.

As Neil mentions, for POD types, they are not default constructed (e.g. set to 0) if not specified in the member initializer list. So there is no redundant initialization done if you set them only in the constructor body, but neither does it cost you anything to use the member initializer list.

Upvotes: 3

Neil Kirk
Neil Kirk

Reputation: 21773

For basic data types such as pointers, integers and floats, it doesn't really matter. The cost of allocating all those sets will dwarf any difference and the compiler can easily optimize the code as constructing and copying basic data types have no side-effects.

For non basic data types, which your generic type may be, it can be less efficient, especially if they have heavy default constructors. This is because, if you don't use the initializer list, the object is created with the default constructor and then will be assigned with a new value, possibly wasting the work that the default constructor did.

Unless there is a specific reason not to, I prefer to always use the initialization list, just in case it is more efficient.

Upvotes: 2

Related Questions