在c++中获取一个类的指针,该类是另一个具有多重继承的类的一部分

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

本文关键字:另一个 一部分 多重继承 指针 c++ 获取 一个      更新时间:2023-10-16

我有一些相互继承的类,但它们使用模板。我想要的是有效地获得一个指向基类的指针和/或引用,就好像它是依赖于模板的其他可能的派生类之一

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;
    // ...
};

派生类既可以继承类a1,也可以继承类b1,这主要是为了节省派生类的空间,因为b1是一个空白类,因此当派生类用模板形参b1实例化时,它不会承载a1的数据成员和虚函数的额外负载。

然而,我现在想从派生(a1)中获得一个指针或引用,它实际上是派生(b1)类型的指针或引用。

我真正要求的是帮助做offsetof()的"好"方式,但使用继承,我可以得到offsetof() a2,我假设这是一个很好的指针派生(b1),因为b1是一个空白类。

我试图获得派生(a1)对象的指针,然后添加sizeof(a1),希望这将是正确的位置,但想知道是否有人有更好的方法的建议。

据我所知,您有例如指向派生的指针,并希望指向a1的指针。由于a1是派生的的直接基类,因此可以通过直接隐式强制转换获得该指针:

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

但是建议您显式地进行强制转换。因为该类总是安全的,可以在编译时解析,所以使用static_cast。

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

执行摘要:指针算术是你不应该在遍历类层次结构时使用的。static_cast和dynamic_cast正是用于这个目的:当你试图做一些危险的事情时,它们会警告你或报错,并且通常比你拥有更多关于确切内存布局的知识。

编辑:你编辑了这个问题,说你想从派生derived。这是不可能的。Static_cast和dynamic_cast不支持改变实例内存布局的操作。强烈建议不要使用任何指针运算,因为您无法知道编译器如何在内存中安排实例的数据字段。

将类b1作为类a1的基类

如果你想做的只是为你的一些对象节省内存空间,那么模板可能不是最好的工具。

由于b1是空的,derived<b1>没有给a2增加任何有用的东西,那么为什么不使用简单的继承class a1 : public a2呢?您可以实例化a1a2中的对象,这取决于您是否需要额外的数据,它们都可以被强制转换为a2(例如,如果您想将它们存储在列表中)。

如果您没有使用模板,只是使用多重继承,假设d是派生类型的实例,但被引用为A1,您可以。

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