关于基础和派生对象的动态转换和地址

Ily*_*lya 1 c++

我正在阅读一些有效的c ++,我意识到我的思路可能不正确.

class A
{
    public:
    void laka()
    {
        const void * raw = dynamic_cast<const void*>(this);
        cout << raw << endl;
    }

    virtual ~A() = 0; 
};

A::~A() {}
class B : public A
{
public:
    void ditka() {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b; 
    cout << &b << endl;
    b.laka();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

书中说通过使用带有*void的dynamic_cast,我会得到一个对象的起始地址,但是所有的地址输出都是相同的.

  1. 当我只输出上面的普通旧&b的地址时,地址是否显示了派生对象的起始地址或b中的基础对象?

  2. 如果我对#1不正确或错误,我如何获得b中每个子对象的起始地址?我只是手动必须偏移,dynamic_cast如何使用它或只是澄清作者的意思?

Jam*_*lis 5

大多数继承实现将第一个基类子对象放在派生类的开头,所以你真的需要两个基类,都有数据成员才能看到这个.考虑:

#include <iostream>

struct B1 { 
    int x; 
    virtual ~B1() { } 
};

struct B2 {
    int y;
    virtual ~B2() { }
};

struct D : B1, B2 { };

int main() {
    D x;
    B1* b1_ptr = &x;
    B2* b2_ptr = &x;
    std::cout << "original address:     " << &x << "\n";

    std::cout << "b1_ptr:               " << b1_ptr << "\n";
    std::cout << "dynamic_cast b1_ptr:  " << dynamic_cast<void*>(b1_ptr) << "\n";

    std::cout << "b2_ptr:               " << b2_ptr << "\n";
    std::cout << "dynamic_cast b2_ptr:  " << dynamic_cast<void*>(b2_ptr) << "\n";
}
Run Code Online (Sandbox Code Playgroud)

示例输出(来自我的机器;您的结果将类似):

original address:     0030FB88
b1_ptr:               0030FB88
dynamic_cast b1_ptr:  0030FB88
b2_ptr:               0030FB90
dynamic_cast b2_ptr:  0030FB88
Run Code Online (Sandbox Code Playgroud)

这告诉我们B1子对象D位于开头,因此它与作为D子对象的对象具有相同的地址.

B2子对象位于不同的地址,但是当你使用dynamic_cast<void*>上的指针到B2子对象,它给你的地址D,其中它是一个子对象的对象.