How can I initialize member variables of a base class in a constructor of a derived class?

Why can't I do this?

class A { public: int a, b; }; class B : public A { B() : A(), a(0), b(0) { } }; 
+94
c ++ inheritance
Sep 13 '11 at 17:09
source share
8 answers

You cannot initialize a and b to b because they are not members of b . They are members of a , so only a can initialize them. You can make them publicly available and then assign to b , but this is not recommended, as this will break encapsulation. Instead, create a constructor in a to allow b (or any subclass of a ) to initialize them:

 class A { protected: A(int a, int b) : a(a), b(b) {} // Accessible to derived classes // Change "protected" to "public" to allow others to instantiate A. private: int a, b; // Keep these variables private in A }; class B : public A { public: B() : A(0, 0) // Calls A constructor, initializing a and b in A to 0. { } }; 
+110
Sep 13 '11 at 17:12
source share

Leaving aside the fact that they are private , since a and b are members of A , they should be initialized by the constructors of A , and not some other class constructors (derived or not).

Try:

 class A { int a, b; protected: // or public: A(int a, int b): a(a), b(b) {} }; class B : public A { B() : A(0, 0) {} }; 
+23
Sep 13 '11 at 17:12
source share
 # include<stdio.h> # include<iostream> # include<conio.h> using namespace std; class Base{ public: Base(int i, float f, double d): i(i), f(f), d(d) { } virtual void Show()=0; protected: int i; float f; double d; }; class Derived: public Base{ public: Derived(int i, float f, double d): Base( i, f, d) { } void Show() { cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl; } }; int main(){ Base * b = new Derived(10, 1.2, 3.89); b->Show(); return 0; } 

This is a working example if you want to initialize the base class data elements present in an object of the Derived class, while you want these values ​​to interact by calling the constructor of the Derived class.

+2
Sep 07 '17 at 9:40
source share

For some reason, no one has listed the easiest way:

 class A { public: int a, b; }; class B : public A { B() { a = 0; b = 0; } }; 

You cannot access the base members in the initializer list, but the constructor itself, like any other member method, can access the public and protected members of the base class.

+2
Sep 28 '18 at 14:30
source share

Although this is useful in rare cases (if it weren’t, the language would allow it directly), look at Base from the Participant Idiom . This is not a code-free solution, you need to add an extra inheritance layer, but it does its job. To avoid template code, you can use increase efficiency

+1
May 01 '14 at 9:45
source share

Why can't you do this? Since the language does not allow to initialize the list of initializers of the base class in the derived class.

How can you do this? Like this:

 class A { public: A(int a, int b) : a_(a), b_(b) {}; int a_, b_; }; class B : public A { public: B() : A(0,0) { } }; 
0
Sep 13 '11 at 18:07
source share

If you do not specify visibility for a class member, the default is "private". You must make your members private or secure if you want to access them in a subclass.

-one
Sep 13 '11 at 17:12
source share

Aggregate classes, such as A in your example (*), must have their members public and not have user-defined constructors. They are initialized by a list of initializers, for example. A a {0,0}; or in your case B() : A({0,0}){} . Members of the base aggregate class cannot be individually initialized in the constructor of the derived class.

(*) To be precise, as was correctly said, the original class A not a collection due to personal non-static elements

-one
Sep 13 '11 at 17:41
source share



All Articles