gpt4 book ai didi

c++ - 理解 C++ 指向父类/基类的指针

转载 作者:IT老高 更新时间:2023-10-28 22:39:45 25 4
gpt4 key购买 nike

有人问我这个面试问题,但我弄错了。 “输出是什么”:我的答案是 135,实际输出是 136。这意味着指向两个父类的指针不相等,即使它们通过了与子类相等的先前测试。我以为我理解 c++ 指针,但这让我很难解释。虽然我想我知道发生了什么,但我不知道为什么。任何可以提供技术解释的c++专家吗?看起来前两个比较在本质上更合乎逻辑,而最后一个比较更文字......

#include <iostream>

class A
{
public:
A() : m_i(0) { }

protected:
int m_i;
};

class B
{
public:
B() : m_d(0.0) { }

protected:
double m_d;
};

class C
: public A, public B
{
public:
C() : m_c('a') { }

private:
char m_c;
};

int main()
{
C c;
A *pa = &c;
B *pb = &c;

const int x = (pa == &c) ? 1 : 2;
const int y = (pb == &c) ? 3 : 4;
const int z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)) ? 5 : 6;

std::cout << x << y << z << std::endl;
return 0;
}

最佳答案

也许如果你打印出 papb 会更清楚发生了什么。

std::cout << "A: " << pa << std::endl;
std::cout << "B: " << pb << std::endl;
std::cout << "C: " << &c << std::endl;

main 的末尾运行它给了我

A: 0xbfef54e0
B: 0xbfef54e4
C: 0xbfef54e0

(您的输出可能不同,重要的是它们并不完全相同)

这是因为 C 对象在内存中的表示方式。由于 C 既是 A 又是 B,因此它需要具有来自每个部分的数据成员。 C 的真正布局是这样的(忽略填充):

int    A::m_i;
double B::m_d;
char C::m_c;

当您将 C* 转换为 A* 时,编译器知道 A 部分从偏移量 0 开始,因此指针值不变。对于 C*B* 它需要偏移 sizeof(int) (加上填充)。此偏移处理是自动为您计算 xy 完成的。对于 z 它被绕过,因为你使用 reinterpret_cast

关于c++ - 理解 C++ 指向父类/基类的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36455992/

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