关于基础和派生对象的动态转换和地址 [英] About dynamic cast and address of base and derived objects

查看:154
本文介绍了关于基础和派生对象的动态转换和地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一些有效的c ++,我意识到我的想法可能不正确。

  class A 
{
public:
void laka()
{
const void * raw = dynamic_cast< const void *>(this);
cout<<原料< 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;
}

这本书指出,通过使用dynamic_cast与* void,地址输出的所有地址相同。


  1. 当我只是输出普通老& b上面是显示派生对象或基本对象在b?中的起始地址的地址


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



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

  #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<< 原地址:< & x<< \\\
;

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

std :: cout<< b2_ptr:< b2_ptr < \\\
;
std :: cout<< dynamic_cast b2_ptr:< dynamic_cast< void *>(b2_ptr)< \\\
;
}

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

 原始地址:0030FB88 
b1_ptr:0030FB88
dynamic_cast b1_ptr:0030FB88
b2_ptr:0030FB90
dynamic_cast b2_ptr:0030FB88

这告诉我们 B1 子对象 D 位于开头,因此它与 D 对象具有相同的地址它是一个子对象。



B2 子对象位于不同的地址,但是当您使用 dynamic_cast<在指向 B2 子对象的指针上的void *> ,它会为您提供 D 对象,它是一个子对象。


I was reading through some of effective c++ and I realized I may be incorrect in my thinking along the way.

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;
}

The book stated that by using dynamic_cast with *void, I would get the starting address of an object however, all of the addresses output of the same.

  1. When I just output the address of the plain old &b above, is the address displayed the starting address of the derived object or the base object within b?

  2. If I was incorrect or wrong about #1, how would I get the starting addresses of each subobject within b? Do I just manually have to offset and how does dynamic_cast work with this or just clarify what the author meant?

解决方案

Most implementations of inheritance put the first base class subobject at the beginning of the derived class, so you really need two base classes, both with data members, to be able to see this. Consider:

#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";
}

Example output (from my machine; your results will be similar):

original address:     0030FB88
b1_ptr:               0030FB88
dynamic_cast b1_ptr:  0030FB88
b2_ptr:               0030FB90
dynamic_cast b2_ptr:  0030FB88

This tells us that the B1 subobject of D is located at the beginning, so it has the same address as the D object of which it is a subobject.

The B2 subobject is located at a different address, but when you use dynamic_cast<void*> on the pointer to the B2 subobject, it gives you the address of the D object of which it is a subobject.

这篇关于关于基础和派生对象的动态转换和地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆