answersLogoWhite

0


Best Answer

The constructor initialisation list is the most efficient method of initialising class members, including primitive members. You use it always and without exception to ensure efficient construction.

Consider the following:

class foo

{

int m_data;

public:

foo(int data=0){ m_data=data; }

foo(const foo& f){ m_data=f.m_data; }

};

This class employs inefficient construction technique by initialising the member variables in the constructor bodies rather than the initialisation list. In other words, m_data is instantiated and initialised in two stages instead of one. It is not unlike the following two stage initialisation:

int m_data;

m_data =0;

A more efficient way of writing these lines is to initialise at the point of instantiation using a compound statement:

int m_data=0;

The same applies to class construction. By using the initialisation list, member variables are initialised at the point of instantiation, as per the following:

class foo

{

int m_data;

public:

foo(int data=0):m_data(data) {}

foo(const foo& f):m_data(f.m_data) {}

};

You will note that primitive members use object-oriented syntax in the initialisation list. This is not merely sugar-coating -- it applies to all members, including base classes. This makes it possible to invoke specific base class constructors, rather than the default constructor that would be implicitly invoked (or the base class copy constructor in the case of a derived class copy constructor).

Consider the following:

class base

{

int m_data;

public:

base(int data=0):m_data(data) {}

base(const base& b):m_data(b.m_data) {}

};

class derived : public base

{

public:

derived(int data=0):base(data) {}

derived(const derived& d):base(d) {}

};

Note how the derived class default constructor invokes the base class default constructor, but passes the data argument to it. Had you not used the initialisation list you'd have to construct base, then derived, and then initialise the base class member via a setter. Clearly the initialisation list is more efficient because the base class can be initialised before derived is even instantiated, which cannot happen until the base class is fully-instantiated.

Note also that the copy constructor specifically invokes the base class copy constructor. Although the argument, d, is not a base class, it is a type of base class, thus there is no need to upcast the argument.

Ultimately, it can be seen that the constructor bodies are largely redundant. You still need a constructor body, even an empty one, but most of the time you will use the body for debug trace code. There will be times, however, where the class initialisation list cannot fully initialise a member because one or more arguments require more complex processing (such as calling a complex setter). In this case, you must use the constructor body. However, you must still perform as much initialisation as is possible via the initialisation list to ensure the most efficient construction method. Only those members that require additional processing need not be initialised, but it costs nothing to initialise them to an arbitrary or default value.

The initialisation list is vital in the case of the copy constructor, as passing an object to a function by value will automatically invoke the copy constructor. If any member variables are embedded objects, or the object is derived from one or more base classes, then their copy constructors will be invoked as well. Therefore it pays to make construction as efficient as possible when copying objects. However, the same applies to any constructor. The more efficient the constructor performs, the better your programs will perform, especially in complex hierarchies where objects may be deeply embedded within other objects that are themselves embedded.

User Avatar

Wiki User

10y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

7y ago

A constructor initialisation list provides the primary means by which class member data is initialised.

Consider the following class definition:

class X {

std::string x;

public:

X (string s) { x=s; }

X (int i=0) { x=to_string(i); }

// ...

};

The member variable x is a user-defined type with a default constructor. As such, x is constructed and initialised before we even reach the constructor body, which is where we perform the actual initialisation. In other words we're performing a two-stage initialisation which can be highly inefficient depending on the complexity of the object we are initialising.

By using an initialisation list we can completely remove the inefficiency:

class X {

std::string x;

public:

X (string s): x {s} {}

X (int i): x {to_string(i)} {}

// ...

};

The initialisation list appears between the closing parenthesis of the argument list and the opening brace of the constructor body, prefixed with a colon. Note that the constructor bodies are now empty. Ideally, we should perform as much initialisation as we possibly can before we enter the constructor body.

In the example above, there is only one member to initialise. If we needed to initialise other members we'd use a comma-separated list of initialisers.

Note that we use braces {} to indicate that an initialisation is taking place. In reality we are actually constructing x via copy construction, so we could have written the list using parenthesis notation:

class X {

std::string x;

public:

X (string s): x (s) {}

X (int i): x (to_string(i)) {}

// ...

};

Whether you use braces or parenthesis is a matter of personal choice. However, there are cases where the notation will change the meaning:

std::vector<int> x {3, 4}; // two elements with values 3 and 4

std::vector<int> y (3, 4); // three elements with value 4

In essence, these are invoking two different constructors:

std::vector<T> (std::initializer_list<T>);

std::vector<T> (size_t size, T value);

Note that a std::initializer_list object is in no way related to a constructor initialiser list.

As well as initialising class member data we can use the initialisation list to initialise base classes:

class Base {

int x;

protected:

Base (int i): x {i} {}

// ...

};

class Derived : public Base {

D (int i): Base {i} {}

};

Note that a derived class cannot directly initialise a private member of its base class, but as long as there's a protected or public constructor available we can invoke that instead.

We can also write one constructor in terms of another:

class X {

int x;

public:

X (int i=0): x {i} {}

X (double d): X {(int) d} {}

// ...

};

Here, the constructor that accepts a double delegates to the default constructor accepting an integer.

Note that base classes and member data must be initialised in the order they are declared. Derived classes are always constructed beginning with the least-derived class. This means that until we reach the constructor body proper the object is only partially constructed. However, the object only becomes a valid object when we return from the constructor body. If an exception is thrown before we return from the constructor body, all objects constructed up to the point of the throw are implicitly destroyed and the object ceases to exist. The call stack will unwind until a suitable handler is found. We can obviously use a try-catch block to catch any exceptions thrown by the constructor body itself, but if we want to catch exceptions thrown by class member constructors we must place the initialiser list itself in a try-catch block:

class X {

std::vector<int> vi;

std::vector<std::string> vs;

public:

X (int, int);

};

X::X (int sz1, int sz2)

try

: vi (sz1), // construct vi with sz1 integers

vs (sz2) // construct vs with sz2 strings

{

// normal construction body goes here

}

catch (std::exception& err)

{

// handle exceptions thrown by the vi or vs initialisers here

}

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: What is a constructor initialization list?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Continue Learning about Engineering

What is the name of the special member function which is automatically called during creation of each class object?

The constructor. The constructor instantiates the object, and can optionally take parameters and has an optional initialization phase. It has no return type, and has the same name as the class itself. The constructor can be overloaded. It cannot be virtual or constant.


Is constructor overloading same as method overloading.yes or no. explain?

yes,because in constructor overloading constructor have same and different parameter list. In method overloading method have same name and different parameter list.


Why constructor is used?

Objects are constructed. You can't make a new object without invoking a constructor. In fact, you can't make a new object without invoking not just the constructor of the object's actual class type, but also the constructor of each of its superclasses including the Object class itself! Constructors are the code that runs whenever you use the keyword new. The constructor typically contains he initialization code that you want to run when someone is instantiating an object of a class that you are coding.


When is it necessary to use member wise initialization list in c plus plus?

Initialization lists makes a difference when we have objects as members. Instead of using default initialization followed by assignment, the initialization list can initialize the object to its final value. This can actually be noticeably faster.When you need to initialize constant member, references and pass parameters to base class constructors, initialization list is the only choice. if you have members of class type with no default constructor available, initialization is the only way to construct your class.There is only one way to initialize base class instances and non-static member variables and that is using the initializer list.If you don't specify a base or non-static member variable in your constructor's initializer list then that member or base will either be default-initialized (if the member/base is a non-POD class type or array of non-POD class types) or left uninitialized otherwise.Once the constructor body is entered, all bases or members will have been initialized or left uninitialized (i.e. they will have an indeterminate value). There is no opportunity in the constructor body to influence how they should be initialized.You may be able to assign new values to members in the constructor body but it is not possible to assign to const members or members of class type which have been made non-assignable and it is not possible to rebind references.For built in types and some user-defined types, assigning in the constructor body may have exactly the same effect as initializing with the same value in the initializer list.If you fail to name a member or base in an initializer list and that entity is a reference, has class type with no accessible user-declared default constructor, is const qualified and has POD type or is a POD class type or array of POD class type containing a const qualified member (directly or indirectly) then the program is ill-formed.


Why you give the constructor name same as class name?

Constructor is just like method in class.it actually used for intialising members of class, lets consider ex. class construct { constrct(){} } in main() you hav to provide.. construct c1=new construct(); new construct() means calling the method of class,and which is used to initailise members of same class implicitly. this it is necessary for constructor to have same name

Related questions

What is the name of the special member function which is automatically called during creation of each class object?

The constructor. The constructor instantiates the object, and can optionally take parameters and has an optional initialization phase. It has no return type, and has the same name as the class itself. The constructor can be overloaded. It cannot be virtual or constant.


Is constructor overloading same as method overloading.yes or no. explain?

yes,because in constructor overloading constructor have same and different parameter list. In method overloading method have same name and different parameter list.


What is the use of a Static Constructor?

Static Constructor - It is a special type of constructor, introduced with C#. It gets called before the creation of the first object of a class(probably at the time of loading an assembly). See example below. Example: public class SomeClass() { static SomeClass() { //Static members may be accessed from here //Code for Initialization } }


What do you mean by initialisation of objects in c plus plus?

Initialization of objects means to provide an initial value for the object. This is usually done by the constructor, or it can be done with an assignment statement.


Why constructor is used?

Objects are constructed. You can't make a new object without invoking a constructor. In fact, you can't make a new object without invoking not just the constructor of the object's actual class type, but also the constructor of each of its superclasses including the Object class itself! Constructors are the code that runs whenever you use the keyword new. The constructor typically contains he initialization code that you want to run when someone is instantiating an object of a class that you are coding.


When is it necessary to use member wise initialization list in c plus plus?

Initialization lists makes a difference when we have objects as members. Instead of using default initialization followed by assignment, the initialization list can initialize the object to its final value. This can actually be noticeably faster.When you need to initialize constant member, references and pass parameters to base class constructors, initialization list is the only choice. if you have members of class type with no default constructor available, initialization is the only way to construct your class.There is only one way to initialize base class instances and non-static member variables and that is using the initializer list.If you don't specify a base or non-static member variable in your constructor's initializer list then that member or base will either be default-initialized (if the member/base is a non-POD class type or array of non-POD class types) or left uninitialized otherwise.Once the constructor body is entered, all bases or members will have been initialized or left uninitialized (i.e. they will have an indeterminate value). There is no opportunity in the constructor body to influence how they should be initialized.You may be able to assign new values to members in the constructor body but it is not possible to assign to const members or members of class type which have been made non-assignable and it is not possible to rebind references.For built in types and some user-defined types, assigning in the constructor body may have exactly the same effect as initializing with the same value in the initializer list.If you fail to name a member or base in an initializer list and that entity is a reference, has class type with no accessible user-declared default constructor, is const qualified and has POD type or is a POD class type or array of POD class type containing a const qualified member (directly or indirectly) then the program is ill-formed.


Why you give the constructor name same as class name?

Constructor is just like method in class.it actually used for intialising members of class, lets consider ex. class construct { constrct(){} } in main() you hav to provide.. construct c1=new construct(); new construct() means calling the method of class,and which is used to initailise members of same class implicitly. this it is necessary for constructor to have same name


Why is the constructor of the Stack Linked List class empty?

The default constructor of a stack is empty because the default value of any container, including a linked list, is an empty container which requires no arguments (all members default to zero).


What is a static block?

A static block is a code block defined with the 'static' keyword and is not inside others blocks. The static block is executed when the class is first loaded and the main purpose is perform all the initialization that may not be appropriate inside a constructor.


How do you declare constructor in cpp?

More or less as you would any other function, except there is no return type (not even void) and an initialisation list can be placed between the declaration and the definition that follows it. The initialisation list allows your constructor to call base class constructors besides the default constructor as well as initialise member variables according to the parameters passed to your constructor. The constructor's name must be the name of the class. Note that if you don't declare any constructors, the compiler generates both a default and copy constructor. If any constructor is declared you lose the default constructor unless you declare one yourself. The copy constructor is always present but must be overridden if your class contains pointers to memory allocated to the class itself. If you don't, the compiler generated copy constructor will perform a member-wise copy of the member variables, resulting in a shallow copy of the pointers themselves, rather than a deep copy of the memory they point to. The copy constructor must accept a constant reference to the same class of object.


What is the method of constructor overloading in c plus plus?

Constructor overloading, just like any function's overloading, is where more than one configuration of parameters exists for the function. Based on the number and type of the parameters, different versions of the function can be resolved by the linker. This is typically used in the constructor as the default constructor (no parameters), the copy constructor (one reference parameter of the same type as the class), and the conversion constructor (any other combination of parameters).


Why is a constructor useful?

Objects are constructed. You can't make a new object without invoking a constructor. In fact, you can't make a new object without invoking not just the constructor of the object's actual class type, but also the constructor of each of its superclasses including the Object class itself! Constructors are the code that runs whenever you use the keyword new.