弄清楚多态类型的c++指针是如何工作的

Figuring out how c++ pointers of polymorphic types work?

本文关键字:何工作 工作 多态 类型 c++ 指针 弄清楚      更新时间:2023-10-16

在windows visual studio编译器上,我有以下代码:

#include <iostream>
#include <string>
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;
    std::cout << "&c address:  " << &c << std::endl;
    std::cout << "pa address:  " << pa << std::endl;
    std::cout << "pb address:  " << pb << std::endl;
    bool paSame(pa == &c);
    bool pbSame = (pb == &c);
    bool pbpaSame = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb));
    std::cout << std::endl;
    std::cout << "paSame:   " << paSame << std::endl;
    std::cout << "pbSame:   " << pbSame << std::endl;
    std::cout << "pbpaSame: " << pbpaSame << std::endl;
    return 0;
}

现在在我的电脑上,当我运行它时,我会得到以下输出:

&c address:  0084FAA4
pa address:  0084FAA4
pb address:  0084FAAC
paSame:   1
pbSame:   1
pbpaSame: 0

为什么&c和pa的地址相同,是因为在内存中对象的布局中,A的数据排在第一位吗?

我理解pb偏移8字节的原因,因为它指向该类型的对象中的内存部分。打印出来的指针是不同的,但这一行仍然评估为真:

bool pbSame = (pb == &c);

为什么?这是有道理的,因为他们是同一个对象,但这方面的规则是什么?由于下一行(正如预期的那样,比较pa和pb的指针)显示指针不同。

由于自动转换规则,表达式(pb == &c)的计算结果为true。在进行比较之前,将&c转换为指向cB部分的B*

来自C++标准草案N3337:

4.10指针转换

3类型为"pointer tocvD"的prvalue,其中D是一个类类型,可以转换为类型为"pointer tocvB"的prvalue,其中BD的基类(第10条)。如果BD的不可访问(第11条)或不明确(10.2条)基类,则需要进行此转换的程序是不正确的。转换的结果是指向派生类对象的基类子对象的指针。