2

As I understand it, when I initialise the base class in the derived class initialiser list, the base class is immediately constructed and base class elements should then be available. If this is right, why doesn't this work?

class Base
{
public:
  int elem;
}

class Derived : public Base
{
  Derived() : Base(), elem(1) {}
  // error: class 'Derived' does not have any field named 'elem'
}

NOTE: In my case I cannot make any changes to Base (it is a fixed interface class).

2
  • I'm dodging your direct question, but -- it's Base's job to initialize that, IMO. Commented Oct 16, 2013 at 14:00
  • @BrianCain In my case Base is an interface containing call-back function objects that an implementation (Derived) can define. Commented Oct 16, 2013 at 14:03

5 Answers 5

2

A constructor can only construct its own class's members. You need to give Base a suitable constructor:

class Base
{
public:
  Base() : elem(23) { }
  int elem;
protected:
  Base(int n) : elem(n) { }
};

class Derived : public Base
{
  Derived() : Base(1) {}
};
Sign up to request clarification or add additional context in comments.

2 Comments

Could you also provide the best-practice approach if Base cannot be changed?
@ausairman: Don't use Base :-) You can always use assignment, but it's hardly "best practice".
2

The initialiser list is used to initialise the direct members and base sub-objects of that class, not members of base classes. Base class members are initialised by the base class constructor, and you can't initialise anything twice.

If you want to reassign the base-class member after it's been initialised, then you can:

Derived() : Base() {elem = 1;}

or you could allow the value to be passed through to the base class's constructor:

explicit Base(int e) : elem(e) {}
Derived() : Base(1) {}

although the note you've added to the question indicates that that's not an option in your particular circumstances.

Comments

0

elem belongs to class Base, so Base is responsible for initializing it.

The correct code looks like this:

class Base
{
public:
  int elem;
  Base(int n) : elem(n) {}
};

class Derived : public Base
{
  Derived() : Base(1) {}
};

Comments

0

You can only initialize members of the class and base classes in initialization list NOT base class members.

If you want to override the value of a base class member do it in the constructor's body.

Comments

0

In that case, you can not initialize elem in the initializer list, and must instead initialize it in the function body.

class Base {
 public:
  int elem;
};

class Derived : public Base {
 public:
  Derived() : Base() {
    elem = 1;
  }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.