开发者

Getting the pointer in C++ for a class that is part of another class with multiple inheritance

开发者 https://www.devze.com 2023-03-24 09:27 出处:网络
I have some classes that inherit from each other but they do so using templates. What I want is to effectively get a pointer and/or reference to one of the base classes as if it is one of the other po

I have some classes that inherit from each other but they do so using templates. What I want is to effectively get a pointer and/or reference to one of the base classes as if it is one of the other possible derived classes dependant upon the templates

class a1
{
public:
   int a;
   virtual void func()
   {
   }
   // other non virtual functions ...
};

class b1
{
public:
    //no members or virtual functions
    //other non virtual functions ...
};

class a2
{
public:
   int a;
   // ...
};

template < class T1 >
class derived : public T1,
                public a2
{
    int a;
    // ...
};

Class derived can either inherit from class a1 or class b1, this is mostly to save space in derived as b1 is a blank class and so when derived is开发者_Python百科 instanciated with template paramater b1 it is not carrying the extra load of the data members and virtual functions of a1.

However I now want to get a pointer or reference from derived(a1) that is really a pointer or reference for a type derived(b1).

What i'm really asking for is help on a "good" way of doing offsetof() but using inheritance where I can get the offsetof() a2, this I am assuming is a good pointer for derived(b1) because b1 is a blank class.

I have tried to get the pointer of derived(a1) object then add on the sizeof(a1) with the hopes that this will be the correct position but wanted to know if anyone else had suggestions of a better way.


As far as I understand you, you have e.g. a pointer to derived<a1>, and want a pointer to a1. Since a1 is a direct base class of derived<a1>, you can obtain this pointer by direct implicit casting:

derived<a1>* instance = whatever();
a1* pointer = instance;

It is however recommended that you make the cast explicit. Since this class is always safe and can be resolved at compile-time, use static_cast.

a1* pointer = static_cast<a1*>(instance);

Executive summary: Pointer arithmetics is something you should not do for traversing class hierarchies. There are static_cast and dynamic_cast available for exactly this purpose: They will warn you or error out when you try to do something dangerous, and generally have much more knowledge about the exact memory layout than you can ever have.

EDIT: You edited the question to say that you want to cast from derived<a1> to derived<b11>. This is not possible. static_cast and dynamic_cast do not support operations that change the memory layout of instances. Any pointer arithmetic is strongly advised against because you cannot know how the compiler arranges the data fields of instances in memory.


Have class b1 as the base class of class a1


If all you want to do is to save memory space for some of your objects then templates are probably not the best tool for that.

As b1 is empty derived<b1> adds nothing useful to a2, so why not using a simple inheritance class a1 : public a2 ? You can instantiate objects from either a1 or a2 depending if you need the additional data and they can all be casted to a2 (for example, if you want to store them in a list).


If you weren't using templates and just Multiple Inheritance, assuming that d is an instance of type Derived but is referenced as A1 you could have.

A1* a = new Derived();
Derived* d = (Derived*)a;
B2* b = d;

The template complicates things though.

0

精彩评论

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