gpt4 book ai didi

c++ - 多重继承指针比较

转载 作者:IT老高 更新时间:2023-10-28 22:38:56 26 4
gpt4 key购买 nike

我有一个类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?

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

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

最佳答案

好吧,不,这行不通。

我个人非常喜欢通过示例学习,所以这里有一个:

#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;
}

我的电脑上的一个运行输出如下:

d: 0035F9FC, b1: 0035F9FC, b2: 0035FA00, d.numberDerived: 0035FA04

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

基本上,你得看看 C++ 内部如何表示一个类的布局:

Address:    Class:
0 Base1
4 Base2
8 Derived

.. 所以总的来说,实例化一个派生类将为派生类的基类分配空间,最后为派生对象本身腾出空间。因为我们这里有 3 个整数,所以就是 12 个字节。

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

您可能可以使用 RIIA 和 sizeof() 来做一些魔术,并确定偏移量 b2 应该有多少与 b1 相当,但随后您会遇到各种其他问题,例如虚拟。总之,我不会推荐这种方法。

更好的方法是像 ialiashkevich 所说的那样强制转换为 Derived*,但是,如果您的对象不是 Derived* 的实例,那么这会带来问题。

(免责声明;我已经有 3 到 4 年没有使用 C++了,所以我可能有点偏离了我的游戏。要温柔 :))

关于c++ - 多重继承指针比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11253100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com