Reputation: 22184
I'm having a specific problem which I've converted into the following Minimal, Complete, and Verifiable example.
#include <iostream>
class Foo {
public:
Foo(int v) : val(v) {}
int get_val() const
{
return val;
}
private:
int val;
};
class Parent {
public:
Parent() : member(0) {}
const Foo& get_member() const
{
return member;
}
protected:
Foo member;
};
// Nothing above this line should be changed
class Child : public Parent
{
public:
// This doesn't work (compile error)
//Child() Parent::member(1) {}
// Nor does this (also a compile error)
//Child() this->member(1) {}
};
int main()
{
Child x;
std::cout << x.get_member().get_val() << std::endl;
return 0;
}
This example demonstrates the issue I'm having in a larger software project where I'm inheriting from an external library but need to directly initialize one of the parent's member variables.
Unfortunately, the Parent class does not have a constructor which parameterizes its member's initialization.
If the Parent
class had a constructor of the form
Parent(int val) : member(val) {}
then I could write a Child
constructor as
Child() Parent::Parent(1) {}
but that is not the case for me.
Question: Is it possible to defer the initialization of a parent's member variable to an inherited class? If so, how?
Upvotes: 3
Views: 739
Reputation: 8018
The easiest way is to initialize Parent::member
in the Child
class constructor body (again):
class Child : public Parent
{
public:
Child() {
Parent::member = 1;
}
};
See the live demo.
As it was clarified in comments, you aren't supposed to assign the
Parent::member
variable.
In such case (let's assume the design was at least something useful), you usually have the ability to apply a setter for certain properties of the parent class member's instance:
class Foo {
Foo(const& Foo) = delete;
Foo& operator=(const& Foo) = delete;
public:
Foo() = default;
int property() const;
void property(int newVal);
};
class Parent {
protected:
Foo member;
public:
Parent() = default;
};
class Child : public Parent {
public:
Child() {
Parent::member.property(1);
};
};
Upvotes: 1
Reputation: 206567
Is it possible to defer the initialization of a parent's member variable to an inherited class? If so, how?
The parent class's member variable is either initialized in its member initialization list or in the body of the constructor. The child class cannot initialize the parent class's member variable in its initializer list -- that is not allowed by the language. The best you can do, it seems, is to set the value of the parent class's member in the body of the child class's constructor.
Example:
struct foo
{
int a;
};
struct bar : foo
{
bar() : a(0) {} // Not allowed
};
but
struct bar : foo
{
bar() { a = 0; } // Allowed
};
Upvotes: 4