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

时间:2014-09-28 19:43:40

标签: c++ pointers

在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

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

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

bool pbSame = (pb == &c);

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

1 个答案:

答案 0 :(得分:1)

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

来自C ++草案标准N3337:

  

4.10指针转换

     

3类型为“指向 cv c的指针”的prvalue,其中D是类类型,可以转换为“指向 cv D“,其中BB的基类(第10条)。如果D是不可访问的(第11条)或不明确的(10.2)基类B,则需要进行此转换的程序格式不正确。转换的结果是指向派生类对象的基类子对象的指针。