简体   繁体   中英

How to solve a mesh inheritance problem in C++

I have the following set of classes that inherit from each other in a mesh way. In the top level, I have abstract classes. Both Abstract_Class_B and Abstract_Class_C inherit from Abstract_Class_A .

In the second level of inheritance, I have the exact implementations of those classes.

  1. Impl_Class_A inherits from Abstract_Class_A .
  2. Impl_Class_B inherits from both Abstract_Class_B and Impl_Class_A .
  3. Impl_Class_C inherits from both Abstract_Class_C and Impl_Class_A .

When I compile the below code, the compiler compiles perfectly if I do not declare any class in the code. But when I start declaring pointer to the classes in the second level, the compiler gives the following error:

undefined reference to `VTT for ns3::Impl_Class_B'
undefined reference to `vtable for ns3::Impl_Class_B'

I used virtual to tackle the typical diamond problem in inheritance, but I am still not able to compile. It makes sense that the compiler gets confused because of this way of inheritance. But my system requires such a design for those classes. Any solution to fix this problem?

The code:

// Top Level (Level 1)

class Abstract_Class_A
{
};

class Abstract_Class_B: virtual public Abstract_Class_A
{
  public:
  uint8_t type;
};

class Abstract_Class_C: virtual public Abstract_Class_A
{
};

// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
  public:
  double angle;
};

class Impl_Class_B: virtual public Abstract_Class_B, Impl_Class_A
{
};

class Impl_Class_C: virtual public Abstract_Class_C, Impl_Class_A
{
};

void test()
{
  Impl_Class_B* test = new Impl_Class_B ();
}

The problem turned out to be related to other virtual functions inside the original classes that I had in my code. The code above works without any problem. During the development, I had encountered other problems so I post her a new code that solves all these problems with comments mentioned next to them:

// Top Level (Level 1)

class Abstract_Class_A
{
     ~Abstract_Class_A (); // To solve source type is not polymorphic” when trying to use dynamic_cast
};

class Abstract_Class_B: virtual public Abstract_Class_A
{
  public:
  uint8_t type;
};

class Abstract_Class_C: virtual public Abstract_Class_A
{
};

// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
  public:
  double angle;
};

class Impl_Class_B: virtual public Abstract_Class_B, virtual public Impl_Class_A // Missing second virtual
{
};

class Impl_Class_C: virtual public Abstract_Class_C, virtual public Impl_Class_A // Missing second virtual
{
};

void test()
{
  Impl_Class_B* test = new Impl_Class_B ();
}

Notes:

  1. With this type of inheritance paradigm, you cannot use static_cast but rather dynamic_cast should be used. Check the following discussion .
  2. When using dynamic_cast you should add a virtual destructor to the top class. Check the following discussion about it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM