Initializing Data Members Using a Member Function

Today I learned a very useful new C ++ 11 feature that allows you to directly initialize data members in a class declaration:

class file_name
{
    public:
    file_name(const char *input_file_name);
    ~file_name();

    private:
    char *file_name=nullptr;  //data_member is initialized to nullptr;
    char *Allocator(int buffer_size);  //code to dynamically allocate requested
                                       //size block of memory.
};

      

Is it possible to take this step further with the new v11 rules and initialize the item with the output of the member function:

class file_name
{
    public:
    file_name(const char *input_file_name);
    ~file_name();

    private:
    char *file_name=Allocator(MAX_PATH);  //data_member is initialized with a block of
                                          //dynamic memory of sufficient size to hold
                                          //and valid file name.;
    char *Allocator(int buffer_size);  //code to dynamically allocate requested
                                       //size block of memory.
};

      

Will this cause problems?

+3


source to share


2 answers


A non-static member function (usually) depends in some way on the state of the object it is called on. If it didn't, there really wouldn't be a reason to make it a non-static member function. Now you want to call a function that depends on the state of your object before the object is fully constructed, i.e. Its invariants that the function can rely on have not yet been established. Therefore, the use of such a function is potentially dangerous, since, for example, a function can access uninitialized variables. Consider this example:

class Fail {
    int a = fun() , b;
    int fun() {return b;}
};

      



Here a

initialized to b

, but with (undefined) value b

. A static member function should be good though.

+1


source


The parenthesis initializer or equal that you use to initialize the member is defined in the standard in section 9.2. Clause 4 says, "An initializer with a binding or equal must appear only in a data member declaration."

Member initialization during construction is described in section 12.6.2.
Clause 10 describes the ordering: 1) most derived base class, 2) direct base class initializer, 3) non-static data members, 4) compound constructor statement.

This means that the base class (es of your class) is always initialized when your bit member or peer initializer is called.



Clause 13 of the section says: "Member functions (including virtual member functions) can be called on an object under development." ... "However, if these operations are performed in the ctor -initializer (or in a function called directly or indirectly from the ctor initializer) before all mem initializers for base classes have completed, the result of the operation is undefined." This last exception is not should happen in your case.

So this statement must be true.

Edit: According to 12.6.2 pt.8, bit-or-equal-initaliszer is only used if the object's constructor does not have a mem-initializer for the element (that is, an initializer with the ":" syntax)

0


source







All Articles