Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to call a function in constructor initializer list?

My gut feeling is it is not. I am in the following situation:

class PluginLoader {    public:       Builder* const p_Builder;       Logger* const p_Logger;        //Others };  PluginLoader::PluginLoader(Builder* const pBuilder)    :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger()) {    //Stuff } 

Or should I change the constructor and pass a Logger* const from where PluginLoader is constructed?

like image 251
nakiya Avatar asked Nov 12 '10 05:11

nakiya


People also ask

Can you call functions in initializer list?

And if we use Initializer List there are only two function calls: copy constructor + destructor call.

Does initializer list run before constructor?

As already answered, initialization lists get completely executed before entering the constructor block. So it is completely safe to use (initialized) members in the constructor body.

What is a constructor initializer list?

Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual bases and non-static data members.

When should a constructor use an initializer?

Initialization lists allow you to choose which constructor is called and what arguments that constructor receives. If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.


2 Answers

That's perfectly fine and normal. p_Builder was initialized before it.

like image 157
GManNickG Avatar answered Sep 20 '22 23:09

GManNickG


What you have is fine. However, I just want to warn you to be careful not to do this: (GMan alluded to this, I just wanted to make it perfectly clear)

class PluginLoader {    public:       Logger* const p_Logger;   // p_Logger is listed first before p_Builder       Builder* const p_Builder;        //Others };  PluginLoader::PluginLoader(Builder* const pBuilder)    :p_Builder(pBuilder),     p_Logger(p_Builder->GetLogger())   // Though listed 2nd, it is called first.                                        // This wouldn't be a problem if pBuilder                                         // was used instead of p_Builder {    //Stuff } 

Note that I made 2 changes to your code. First, in the class definition, I declared p_Logger before p_Builder. Second, I used the member p_Builder to initialize p_Logger, instead of the parameter.

Either one of these changes would be fine, but together they introduce a bug, because p_Logger is initialized first, and you use the uninitialized p_Builder to initialize it.

Just always remember that the members are initialized in the order they appear in the class definition. And the order you put them in your initialization list is irrelevant.

like image 41
Benjamin Lindley Avatar answered Sep 22 '22 23:09

Benjamin Lindley