0

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

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)中获取一个指针或引用,它实际上是派生(b1)类型的指针或引用。

我真正想要的是帮助以“好”的方式执行 offsetof(),但使用继承,我可以获得 offsetof() a2,我假设这是一个很好的衍生(b1)指针,因为 b1 是空白班。

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

4

4 回答 4

2

据我了解,您有一个指向derived<a1> 的指针,并且想要一个指向a1 的指针。由于 a1 是 derived<a1> 的直接基类,因此可以通过直接隐式强制转换来获取此指针:

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

但是,建议您明确强制转换。由于此类始终是安全的并且可以在编译时解析,因此请使用 static_cast。

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

执行摘要:指针算术是遍历类层次结构时不应该做的事情。有 static_cast 和 dynamic_cast 可用于此目的:当您尝试做一些危险的事情时,它们会警告您或出错,并且通常比您对确切的内存布局有更多的了解。

编辑:您编辑了问题,说您想从派生<a1> 转换为派生<b11>。这是不可能的。static_cast 和 dynamic_cast 不支持更改实例内存布局的操作。强烈建议不要使用任何指针算法,因为您不知道编译器如何在内存中排列实例的数据字段。

于 2011-07-29T18:08:37.353 回答
0

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

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

模板虽然使事情复杂化。

于 2011-07-29T19:57:20.557 回答
0

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

既然b1为空derived<b1>并没有什么用处a2,那么为什么不使用简单的继承class a1 : public a2呢?您可以根据是否需要附加数据来实例化对象,a1并且a2可以将它们全部转换为a2(例如,如果要将它们存储在列表中)。

于 2011-07-29T18:38:44.697 回答
0

将 b1 类作为 a1 类的基类

于 2011-07-29T18:21:36.093 回答