Q: c++: What is the solution of virtual derivation grandpa constructing propagation problem?
A: The solution is very simple: delete default constructor of the very super-base class.
// code-(2)
#include <iostream> namespace manda { // The very super-base class. class grandpa { protected: int x{0}; public: grandpa() = delete; grandpa(int x): x{x} {} }; class father: virtual public grandpa { protected: int y{0}; public: father(int x, int y): grandpa{x}, y{y} {} }; class man: public father { protected: int z{0}; public: man(int x, int y, int z): grandpa{x}, father{x, y}, z{z} {} public: void print() const { std::cout << "(x, y, z) = " << "(" << x << ", " << y << ", " << z << ")" << std::endl ; } }; } int main() { manda::man man{7, 4, 9}; man.print(); }
Output:
(x, y, z) = (7, 4, 9)
What will happen if constructor of manda::man does not propagate to manda::grandpa?
// code-(2)
class man public father { private: int z{0}; public: man(int x, int y, int z): // grandpa{x}, father{x, y}, z{z} {} ... ... };
The compiling will help you to correct code by an error message:
error: use of deleted function ‘manda::grandpa::grandpa()
What is the virtual derivation grandpa constructing propagation problem?
When c++ cascaded virtual derivation
is enabled,
manda::man constructor transfers parameters to manda::father
constructor,
we expect then the manda::father constructor will transfer
parameters to manda::grandpa constructor,
however it does not work:
manda::father constructor does not transfer parameters to manda::grandpa constructor,
Because they are virtual derivation !
Instead,
manda::man constructor will implicitly call a default constructor of manda::grandpa
directly,
which will let wrong parameters be transferred:
Like code-(2). (and if the default constructor of manda::grandpa is not deleted.)
To let the correct parameters
be transferred from manda::man constructor to manda::grandpa constructor,
we can let the manda::man consructor propagate manda::grandpa constructor explicitly:
// code-(3)
class man public father { private: int z{0}; public: man(int x, int y, int z): grandpa{x}, // explicit propagate father{x, y}, z{z} {} ... ... };
However, it has an easy-to-make-mistake
problem:
user programming will be more easy to miss propagating to grandpa
constructor,
and especially, if the grandpa code is coded at a third-party
library,
user programming will not realize it at all.
The solution is delete the default
constructor of grandpa like this article,
then the compiling will point
out the error by an error message.
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
Tue Aug 11 12:46:26 AM UTC 2026
//////////////////////////////////////////////////////////////////////
+
Powered by:
B2 Build
| boost quickbook
+
+