Initialize parent's protected members with initialization list (C++)
It is not possible in the way you describe. You'll have to add a constructor (could be protected) to the base class to forward it along. Something like:
class Parent
{
protected:
Parent( const std::string& something ) : something( something )
{}
std::string something;
}
class Child : public Parent
{
private:
Child() : Parent("Hello, World!")
{
}
}
c++ instantiating a protected member from parent class
The member intializer list following the :
after the constructor head does not do any assignment of variables. Instead it specifies for each non-static direct data member and base class of the class an initializer with which these members or base classes are going to be initialized.
name
is not a direct member of trouble_maker
. It is not trouble_maker
's job to initialize it. That is person
's job.
Members and base classes are initialized top-down. First the bases class are initialized, then the direct members of the class. While the person
subobject is created and initialized, the derived trouble_maker
object doesn't even exist yet. Therefore it must be person
that initializes name
.
If you want to initialize name
differently in trouble_maker
than in person
, you need to write a constructor for person
that does the initialization for trouble_maker
. trouble_maker
can then call this constructor in the member initializer list, the same way you already do here: : person(age),
.
The later this->name = name;
is not initialization, but assignment. Since you made name
protected
rather than private
, trouble_maker
is allowed to assign to name
, but it is still not able to initialize name
without going through a constructor of person
.
Initializer List for Derived Class
An object can only be initialized once. (The exception is if you initialize it and then destroy it; then you can initialize it again later.)
If you could do what you're trying to do, then base::data
could potentially be initialized twice. Some constructor of base
might initialize it (although in your particular case it doesn't) and then the derived
constructor would be initializing it, potentially for a second time. To prevent this, the language only allows a constructor to initialize its own class's members.
Initialization is distinct from assignment. Assigning to data
is no problem: you can only initialize data
once but you can assign to it as many times as you want.
You might want to write a constructor for base
that takes a value for data
.
class base{
protected:
int data;
base(int data): data(data) {}
};
class derived: public base{
public:
derived(): base(42) {}
};
int main(){
derived d{}; // note: use curly braces to avoid declaring a function
}
Initialise protected data members from derived class constructor
Is it that I can't initialise protected members using Initalizer list or something?
Right. Only class' own members can be initialized in constructor initializer list (You can, OTOH, assign to them in constructor's body). The base subobjects are initialized first.
You'll need to somehow delegate the work to one of base class' constructors:
class Base {
explicit Base(int i) : m(i)
{}
protected:
int m;
};
class Derived : public Base {
explicit Derived(int i) : Base(i)
{ }
};
How to initialize members of template-base class from derived constructor initializer list?
You need to initialize the base class in the member initialization list of the derived class. Since your base doesn't have a constructor you can use curly brace initialization (uniform initialization) like
template <typename T>
struct base {
T a;
};
template <typename T>
struct derived : base<T> {
derived(T v) : base<T>{v} {}
};
How can I initialize base class member variables in derived class constructor?
You can't initialize a
and b
in B
because they are not members of B
. They are members of A
, therefore only A
can initialize them. You can make them public, then do assignment in B
, but that is not a recommended option since it would destroy 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's constructor, initializing a and b in A to 0.
{
}
};
C++populating base class protected member using derived class constructor
The problem here is that you are initializing your inherited myObject
in the initialization list. When an object of the derived class is created, before entering the body of the constructor of the derived class the constructor of the base class is called (by default, if base class has default or no parameter constructor, otherwise you have to explicitly call the constructor in the initialization list).
So, when you do :: Class Child:public someNamespace::Base
your constructor for the base class has not yet been called, which is why your compiler complains :: Child class does not have a field called myObject, that is you are actually trying to assign a value to something which has not yet been declared and defined! It will get defined after the constructor the Base
class enters its execution.
So, your Child
class constructor will look something like this ::
Child(someType x) {
myObject = x;
}
Working ideone link :: http://ideone.com/70kcdC
I found this point missing in the answer above, so I thought it might actually help!
Initialize first entries of an array of objects in class constructor initialization list
The problem is that B
hides its members by default as private
because it is a class
. Declare B
a struct, or expose int x, y
as public
to be able to use aggregate initialization:
class A{
class B{
public:
int x, y;
};
B arrB[10] = {{1,2}};
public:
A();
};
The second problem is that you're not using aggregate initialization properly.
A::A(): arrB[0](1, 2), arrB[1](3, 4) {}
Should be
A::A(): arrB{{1, 2}, {3, 4}} {}
Demo
Related Topics
Overriding Public Virtual Functions with Private Functions in C++
What Are Primitive Types Default-Initialized to in C++
Static and Extern Global Variables in C and C++
How to Use Visual Studio 2010's C++ Compiler with Visual Studio 2008's C++ Runtime Library
Why Would Someone Use #Define to Define Constants
How to Write C/C++ Code Correctly When Null Pointer Is Not All Bits Zero
Void Pointers: Difference Between C and C++
Spiral Rule and 'Declaration Follows Usage' for Parsing C and C++ Declarations
Check Traits for All Variadic Template Arguments
C++ Function to Count All the Words in a String
Dynamic Aligned Memory Allocation in C++11
Detecting Constexpr with Sfinae
How to Programmatically Gain Root Privileges
Why Is It Illegal to Take the Address of an Rvalue Temporary
/Usr/Lib/X86_64-Linux-Gnu/Libstdc++.So.6: Version Cxxabi_1.3.8' Not Found