将指向基类的指针转换为指向导出类的指针 [英] Casting pointer-to base class into a pointer-to derived class

查看:173
本文介绍了将指向基类的指针转换为指向导出类的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了一些关于在C ++中铸造。来自C的背景,使用正常(类型)转换是常见的 void * ,但对于C ++,是 dynamic_cast reinterpret_cast static_cast p>

问题/问题/问题是当在基指针和派生指针之间进行转换时,应该使用以上类型转换。



我们的数据存储存储一个指向基类( B )的指针。函数分配派生的指针( D )。



代码示例如下:

  class B 
{int _some_data; }
class D:public B
{int _some_more_data; }

代码看起来像这样:

  D * obj = new D; 
obj-> _some_data = 1;
obj-> _some_more_data = 2;
< store obj>

稍后我们访问数据时:

  B * objB =< get out data> 
if(objB-> _some_data == 1)
{D * objD =(D *)objB; < do some processing> }

现在我关心的演员是 D * objD =



谢谢。

解决方案

对于你知道但编译器没有的相关类型,使用 static_cast



但在你的情况下你不应该施放。




我们的数据存储存储指向基类(B)的指针。函数分配派生指针(D)。


这是为了丢弃信息一个好主意。有人意识到,这不是一个好主意,事实上它不能工作,因此试图将该类型信息动态保存在 B :: _ some_data 的值。总效果:抛弃 C ++支持以处理类型信息,并替代非常脆弱和脏的自制的解决方案。



利用C ++支持,使B成为一个多态类,即至少有一个 virtual 成员:

  struct B {virtual〜B(){}}; 

我删除了数据成员 _some_data 它的唯一目的是跟踪动态类型,现在C ++支持这样做,实际上通过一个所谓的vtable指针在对象中。总对象大小可能是相同的。然而,bug的吸引力和纯粹的丑陋减少了一些数量级。 ; - )



然后,

  struct D 
:B
{
int some_more_data_;
D(int v):some_more_data_(v){}
};

然后,使用多态类,您的处理代码可以使用安全 dynamic_cast ,如下所示:

  B * const objB = getOutData ; 
if(D * const objD = dynamic_cast< D *(objB))
{
//使用objD进行一些处理
}

现在这个手动动态类型检查仍然很脏,并且反映了一个非OO系统架构。使用对象定向,数据有效地包含指向适当的专用操作的指针,而不是检查它们被给予什么类型的数据。但我认为最好一次采取一个步骤,作为第一步:摆脱脆弱的bug吸引自己的动态类型检查计划,并使用相对清洁的超级新鲜漂亮的嗅到好看等等C ++支持。 : - )


I have read a bit about casting in C++. Coming from a C background, using normal (type) casting is common for things like void * but for C++, there are dynamic_cast, reinterpret_cast, static_cast, etc.

The problem/issue/question is about which of the above casts should be used when a conversion between a base pointer and a derived pointer.

Our data storage stores a pointer to a base class (B). The functions allocate the derived pointers (D).

The code example is as follows:

class B
{ int _some_data; }
class D : public B
{ int _some_more_data; }

The code then looks something like:

D *obj = new D;
obj->_some_data = 1;
obj->_some_more_data = 2;
<store obj>

Then later when we access the data:

B *objB = <get out data>
if (objB->_some_data == 1)
{ D *objD = (D *) objB; <do some processing> }

Now the cast I am concerned about is D *objD = (D *) objB.

Which cast should we be using?

Thanks.

解决方案

For related types that you know about but the compiler don't, use a static_cast.

But in your case you should not cast at all.

You write that

Our data storage stores a pointer to a base class (B). The functions allocate the derived pointers (D).

That is to throw away information, which is not a good idea. Someone realized that it's not a good idea, that in fact it could not work, and therefore tried to keep that type information dynamically in the value of B::_some_data. The total effect: to throw away the C++ support for handling that type information, and substituting a very fragile and dirty homegrown solution.

In order to leverage the C++ support, make B a polymorphic class, i.e. with at least one virtual member:

struct B { virtual ~B() {} };

I removed the data member _some_data since apparently its only purpose was to keep track of the dynamic type, and now the C++ support does that, in practice via a so called "vtable pointer" in the object. The total object size is probably the same. The bug attraction and sheer ugliness is, however, reduced by some orders of magnitude. ;-)

Then,

struct D
    : B
{
    int some_more_data_;
    D( int v ): some_more_data_( v ) {}
};

And then, with polymorphic classes, your processing code can use a safe dynamic_cast, as follows:

B* const objB = getOutData();
if( D* const objD = dynamic_cast<D*>( objB ) )
{
    // do some processing using objD
}

Now this manual dynamic type checking is still very dirty and reflects a non-OO system architecture. With object oriententation, instead of operations checking what kind of data they have been given, the data effectively contains pointers to appropriate specialized operations. But I think it might be best to take one step at a time, and as a first step the above: getting rid of the fragile bug-attracting homegrown dynamic type checking scheme, and using relatively clean super-duper fresh nice-smelling good looking etc. C++ support for that. :-)

这篇关于将指向基类的指针转换为指向导出类的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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