任何人都可以解释一下,如果这种方式可以向下倾斜,或者我们应该使用明确的类型演员吗?
#include<iostream>
using namespace std;
class base {
public:
virtual void func() { cout<<"Base \n"; }
void fun() { cout<<"fun"; }
};
class derived1 : public base {
public:
void func() { cout<<"Derived 1\n"; };
void fun() { cout<<"fun1"; }
};
class derived2 : public derived1 {
public:
void func() { cout<<"Derived 2\n"; }
void fun() { cout<<"fun2"; }
};
int main()
{
base * var = new derived1;
((base *) var)-> fun();
((derived1 *) var)-> fun();
((derived2 *) var)-> fun();
// How does this work?
}
答案 0 :(得分:1)
((base *) var)-> fun();
和((derived1 *) var)-> fun();
有效,但不是很好的做法。您应该使用C++
样式广告(static_cast
,dynamic_cast
..)而不是c-style
投射。
((derived2 *) var)-> fun();
无效,因为var
并非属于derived2
类。如果您使用dynamic_cast
进行投射,则会失败。但是这里因为C++
中的对象对齐而有效。在代码部分中,通常会在基本成员之后以及定义它们的顺序放置派生成员。因此,在这种情况下,derived1::fun
和derived2::fun
将从相同的偏移量开始,因此调用它。虽然转换为derived2*
后的对象无效,但它起作用,因为fun
不访问该类的任何成员。但是这种行为是不可预测的,不能依赖于此或使用此类代码。
答案 1 :(得分:0)
首先,在这里base * var = new derived1;
你正在进行投射。
其次,使用dynamic_cast
进行下击会更安全。
derived1 *d1 = dynamic_cast<derived1*>(var);
if(d1) d1->fun();
derived2 *d2 = dynamic_cast<derived2*>(var); // will return NULL
if(d2) d2->fun();