多重继承:在派生的同级类之间向下转换? [英] multiple inheritance: downcasting across derived-sibling classes?

查看:76
本文介绍了多重继承:在派生的同级类之间向下转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的,

提前谢谢.
我正在DevC ++环境中从事C ++项目.我想知道以下程序的工作情况如何?

Dear,

Thanks in advance.
I am working on C++ project in DevC++ environment. I am wondering how following program is working fine?

#include <iostream>
using namespace std;

class Base{};
class Derived1:public Base{};
class Derived2:public Base
{
      public:
             float Derived2Data;
             void Derived2Fun(){}
      void Derived2Fun1()
      {
           Derived2Data = 10.9;
      }
};

void main()
{
      Derived1 obj2;
        Base* pBase1 = &obj2;
        ((Derived2*)pBase1)->Derived2Fun(); // no error
        ((Derived2*)pBase1)->Derived2Fun1(); // no error
        cout<<"Value of Derived2Data is:"<<((Derived2*)pBase1)->Derived2Data<<endl;
}




输出:Derived2Data的值为:10.9

即使这是错误的类型转换.向上转换->向下转换.即使这样,也没有运行时以及编译错误.




Output: Value of Derived2Data is: 10.9

even though this is a wrong typecasting. upcasting->cross-downcasting. even then there is no run-time as well as compilation error. it may cause disasters, this is very unsafe?

推荐答案

///我想知道以下程序的工作情况如何?

请也将sizeof(Derived1 obj1)和sizeof(Derived2 obj2)放出;)
// I am wondering how following program is working fine?

Please put also the sizesof(Derived1 obj1) and sizeof(Derived2 obj2) out ;)


首先,对C ++类型使用C样式类型转换是一个非常糟糕的主意.请改用dynamic_caststatic_cast等(并确保确切知道何时使用哪种方法:请参见 http: //www.cplusplus.com/doc/tutorial/typecasting/ [ ^ ])

第二,没有虚函数,继承就没有意义.但是我现在假设这只是您过于专注于所讨论的代码. [edit]与问题无关-请忽略[/edit]

第三,C风格的类型转换将始终被编译器接受:它们基本上告诉编译器您比编译器更了解. (IME通常是一个误解,在这种情况下肯定是这样)

最后,这是可行的,因为您很幸运:这里发生的是,在堆栈上创建了类型为Derived1的对象,并具有适合该对象的适当大小.然后,向您的编译器表明实际上这是一个Derived2类型的对象.因为您使用的是C风格的类型转换,所以系统将毫无疑问地满足您的要求,并将Derived2的内存布局覆盖在obj2占用的内存上.只要您不尝试使用虚函数或数据成员,这就会起作用,但是当您调用Fun1()时,您实际上是在写入数据成员:由于本来分配的内存不足以容纳Derived2,您正在写超出该内存范围的内容.

通常,这会导致其他变量损坏,但是在这种情况下,您似乎很幸运.我相信在内部,堆栈变量以相反的声明顺序存储:在这种情况下,首先是pBase,然后是obj2.如果不是这样,您可能会覆盖pBase1,并且代码的最后一行可能会崩溃,
First of all, using C-style typecasts on C++ types is a very bad idea. Use dynamic_cast, static_cast, etc. instead (and make sure you know exactly when to use which: see http://www.cplusplus.com/doc/tutorial/typecasting/[^] )

Second, without virtual functions, inheritance doesn''t make sense. But I''ll assume for now this is just an oversimplifaction on your part to focus on the code in question. [edit]does not relate to the question - please ignore[/edit]

Third, C style typecasts will always be accepted by the compiler: they basically tell the compiler that you know better than the compiler does. (IME this is very often a misconception, and in this case it definitely is)

Last, this works because you were lucky: What happens here is that on the stack, an object of type Derived1 is created, with the appropriate size to fit such an object. Then, you the compiler that in truth this is an object of type Derived2 instead. Because you used C-style typecasting the system will comply to your wish without question and overlay the memory layout of Derived2 over the memory occupied by obj2. This will work for as long as you don''t try to use virtual functions, or data members, but when you call Fun1(), you actually write into a data member: Since the memory orginally allocated is not big enough to fit Derived2, you''re writing outside the bounds of that memory.

Normally, this causes other variables to be corrupted, but it seems that you were lucky in this case. I believe that internally, the stack variables are stored in reverse order of declaration: in this case pBase first, then obj2. If it had been the other way round, you would have overwritten pBase1 and the last line of your code would likely have crashed,


这篇关于多重继承:在派生的同级类之间向下转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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