Может ли кто-нибудь объяснить мне, если это нормально, чтобы снизить рейтинг, или мы ДОЛЖНЫ использовать явное приведение типов для него?
#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?
}
((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
не имеет доступа ни к одному из членов класса. Но это поведение непредсказуемо, и не должен полагаться на это или использовать этот вид кода.
Прежде всего, здесь 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();