gpt4 book ai didi

c++ - 从基类指针访问派生类成员

转载 作者:搜寻专家 更新时间:2023-10-31 01:01:19 26 4
gpt4 key购买 nike

我真的很困惑。我遇到了以下情况,其中 C 从 A 和 B 继承,但根据事物的分配方式,我会得到不同的行为:

  • 如果我新建一个C实例,并将它存储在一个A指针中,然后将它的值赋给一个 >B指针,用A指针调用A的方法,用指针调用B的方法B 指针,我得到了奇怪的东西...(参见测试 1)。

  • 如果我新建一个C实例,并将它存储在一个C指针中,然后将它的值赋给一个 >AB 指针,并使用A 指针调用A 的方法,以及B 的方法B 指针,我得到了我所期望的...(参见测试 2)。

我的问题是:为什么测试 1 的行为方式如此?

A 级

class A
{
public:
A() { aMember = 'A'; }
virtual ~A() {}
virtual char getAMember() { return aMember; }
private:
char aMember;
};

B 级

class B
{
public:
B() { bMember = 'B'; }
virtual ~B() {}
virtual char getBMember() { return bMember; }
private:
char bMember;
};

C级

class C : public A, public B
{
public:
C() : A(), B() {}
virtual ~C() {}
};

有 Test1 和 Test2 的 Main

#include <cstdio>

int main(void)
{
C* c;
A* a;
B* b;

printf("Test 1\n");

a = new C();
b = (B*)a;

printf("a->getAMember(): %c\n",a->getAMember()); // prints A
printf("b->getBMember(): %c\n",b->getBMember()); // prints A ?!

printf("Test 2\n");

c = new C();
a = c;
b = c;

printf("a->getAMember(): %c\n",a->getAMember()); // prints A
printf("b->getBMember(): %c\n",b->getBMember()); // prints B

return 0;
}

最佳答案

您正在使用邪恶的 C 风格转换,在本例中相当于 reinterpret_cast。这将 A 子对象的地址重新解释为 B 子对象的地址,实际上是在另一个地址;转换无效,如果您尝试通过该指针访问 B,则会出现未定义的行为。

使用dynamic_cast 在同一完整对象的多态基类子对象之间安全地进行交叉转换(如果您正在转换指针,请记住检查结果);或 static_cast 到派生类(在本例中,到 C*),如果您绝对确定您指向的是该类型的对象。

在第二种情况下,您可以安全地从派生类转换为基类,因此一切都已明确定义,无需任何转换。

关于c++ - 从基类指针访问派生类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29371307/

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