Унизительная процедура

Может кто-нибудь объяснить мне, если это нормально, чтобы уменьшить это, или мы ДОЛЖНЫ использовать явное приведение типов для него?

#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?
}

2 ответа

Решение

((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();
Другие вопросы по тегам