5
votes

I have a purely virtual class defined as such:

class BaseClass {
 protected:
  const int var;
 public:
  void somefun() = 0; // what I mean by a purely virtual class
  // stuff...
};

If I don't add a constructor defined as such:

BaseClass(const int & VAR) : var(VAR) {};

that I would have to subsequently use in ever derived class, my derived class can't initialize the const variable var to whichever value it wants to. Now I actually understand what's going on here. Before constructing a derived class, a constructor of the base class is called, at which point const member variables must be initialized. My question is not a "how do I make my code work" kind of question, that's already been done. My question is about why the compiler thinks it's necessary. For a purely virtual class, shouldn't I be allowed to write something like:

class DerivedClass : BaseClass {
 public:
  DerivedClass() : var(SOME_VALUE) {};
}

If the compiler knows that a call to a BaseClass constructor will necessarily be followed by a call to some derived class constructror (since an object of abstract type can never be instantiated) shouldn't it give us a bit more leeway?

Is this all a consequence of how C++ chooses to get around the Diamond problem? Even if that was the case, shouldn't the compiler at least somehow allow for the possibility that const member variable of purely virtual functions will be defined in derived classes? Is that too complicated or does that mess with the C++ solution to the Diamond problem?

Thanks for the help everyone.

3
Probably because the compiler would have to enforce the rule that derived classes must initialize protected members of their base class, which would be a bit convoluted.Oliver Charlesworth
I think it's true that it does that. But is that really necessary in this situation?ticster

3 Answers

6
votes

It's not "purely virtual" (whatever you mean by that) - it contains a data member.

Class members can only be initialised by the initialiser list of a constructor of that class, not of a derived class. That's how object initialisation is specified: all members that are initialised, are initialised before the constructor body begins.

Constant objects must be initialised, since they can't be assigned a value later.

Therefore, a class with a constant data member must initialise it in each constructor.

2
votes

For a purely virtual class, shouldn't I be allowed to write something like

No, but you can(and in this case should) write something like this:

class DerivedClass : BaseClass {
 public:
  DerivedClass() : BaseClass(SOME_VALUE) {};
};
2
votes

The construction of an object occurs in a specific order. The base class must be fully constructed before the constructor of a derived class is run, so that the derived constructor is working with a fully formed and valid base object. If the initialization of base member variables were put off until the construction of the derived class, this invariant would be broken.