开发者

C++: Initialization of inherited field

开发者 https://www.devze.com 2023-01-21 05:29 出处:网络
I\'ve a question about initialization of inherited members in constructor of derived class. Example code:

I've a question about initialization of inherited members in constructor of derived class. Example code:

class A
    {
public:
    int m_int;
    };

class开发者_Python百科 B: public A
    {
public:
    B():m_int(0){}
    };

This code gives me the following output:

In constructor 'B::B()': Line 10: error: class 'B' does not have any field named 'm_int'

(see http://codepad.org/tn1weFFP)

I'm guessing why this happens? m_int should be member of B, and parent class A should already be initialized when initialization of m_int in B happens (because parent constructors run before member initialization of inherited class). Where is a mistake in my reasoning? What is really happens in this code?

EDIT: I'm aware of other possibilities to initialize this member (base constructor or assignment in derived constructor), but I want to understand why is it illegal in the way I try it? Some specific C++ language feature or such? Please point me to a paragraph in C++ standard if possible.


You need to make a constructor for A (it can be protected so only B can call it) which initializes m_int just as you have, then you invoke :A(0) where you have :m_int(0)

You could also just set m_int = 0 in the body of B's constructor. It is accessible (as you describe) it's just not available in the special constructor syntax.


In order to construct an instance of class B you first instantiate an instance of class A. During that instantiation m_int gets initialized. It's after that intialization that b's constructor is called, so you can't reinitialize m_int. If that's your goal then you can implement a constructor for A that takes an int and then call that in B's initialization list:

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};


What you want is this:

class A{
public:
    A() : m_int(0);
    int m_int;
};

so that m_int is initialized in the correct place.

Edit:

From a comment above, the reason the compiler complains when you try to initialize the m_int variable in B is that it's already been initialized by the constructor of A. That is, you can't re-initialize something, only reassign. So, you can reassign like Ben Jackson stated above or you can initialize in the proper place.


make a constructor in A and use B(): A(2) {} insteed of B():m_int(0){} its working.


Go with the first suggestion by Ben Jackson. The second one (i.e. set m_int = 0 in the body of the constructor) is OK as long as m_int is not a const. I believe this would not work if m_int were const (but the first suggestion would), which, unless you intend to make mutable, I would recommend.

So, do:

class A {
protected:
    A():m_int{0}{} // Move constructor to parent class
    
public:
    const int m_int;
    auto print() {std::cout << m_int << std::endl;} // For example
};

class B: virtual public A {
public:
    B():A(){}
};

Example:

auto x {B()};
x.print() // Prints 0
0

精彩评论

暂无评论...
验证码 换一张
取 消