多重继承指针比较

Luc*_*iel 15 c++ inheritance pointers multiple-inheritance

我有一个Derived直接从两个基类继承的类,Base1Base2.我想知道一般来说,将指针与基类进行比较以确定它们是否是同一个Derived对象是否安全:

Base1* p1;
Base2* p2;

/*
 * Stuff happens here. p1 and p2 now point to valid objects of either their
 * base type or Derived
 */

//assert(p1 == p2); //This is illegal
assert(p1 == static_cast<Base1*>(p2)); //Is this ok?
assert(static_cast<Derived*>(p1) == static_cast<Derived*>(p2)); //How about this?
Run Code Online (Sandbox Code Playgroud)

指针保证有效,但不一定指向Derived对象.我的猜测是这可能很好,但我想从技术C++的角度来看它是否可以.我实际上从不对指针进行任何操作,我只是想知道它们是否指向同一个对象.

编辑:如果我可以保证p1p2指向Derrived对象似乎是安全的.我基本上想知道如果它们不是 - 如果一个或两个都指向基础对象,它是否安全,那么比较是否必然会失败?同样,我可以保证指针有效(即,p1永远不会指向Base2对象,反之亦然)

cwa*_*wap 6

嗯,不,它不会起作用.

我个人是学习的忠实粉丝,所以这里有一个:

#include <iostream>

class Base1
{
public:
    Base1()
    {
        numberBase1 = 1;
    }

    int numberBase1;
};

class Base2
{
public:
    Base2()
    {
        numberBase2 = 2;
    }

    int numberBase2;
};

class Derived : public Base1, public Base2
{
public:
    Derived()
    {
        numberDerived = 3;
    }

    int numberDerived;
};

int main()
{
    Derived d;
    Base1 *b1 = &d;
    Base2 *b2 = &d;

    std::cout << "d: " << &d << ", b1: " << b1 << ", b2: " << b2 << ", d.numberDerived: " << &(d.numberDerived) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的计算机上的一个贯穿输出:

d: 0035F9FC, b1: 0035F9FC, b2: 0035FA00, d.numberDerived: 0035FA04
Run Code Online (Sandbox Code Playgroud)

Soo ..如果我们将d的地址定义为0,则b1为0,b2为+4,d的数量为+8.这是因为我机器上的int长4个字节.

基本上,您必须查看C++内部表示类的布局:

Address:    Class:
0           Base1
4           Base2
8           Derived
Run Code Online (Sandbox Code Playgroud)

总而言之,实例化Derived类将为派生类的基类分配空间,最后为派生对象本身腾出空间.由于这里有3个整数,因此它将是12个字节.

现在,你问的问题(除非我误解了一些东西)是你可以比较不同基类指针的地址,看看它们是否指向同一个对象,答案是否定的 - 至少不是直接的,在我的例子中,b1将指向0035F9FC,而b2将指向0035FA00.在C++中,这种偏移都是在编译时完成的.

你可以用RIIA和sizeof()来做一些魔术,并确定偏移量b2应该与b1相当多少,但是你会遇到各种其他问题,比如虚拟.简而言之,我不推荐这种方法.

一个更好的方法是投射到Derived*,就像ialiashkevich所说的那样,如果你的对象不是Derived*的实例,那就会产生问题.

(免责声明;我在3 - 4年内没有使用过C++,所以我的游戏可能有些偏差.温柔:))


小智 5

Derived*在比较之前进行投射是正确的方法.

有一个类似的话题:C++指针多继承的乐趣