Вызов метода производного класса для объекта базового класса - PullRequest
2 голосов
/ 05 января 2011

Я написал несколько строк кода, которые, я думаю, не должны компилироваться. Я вызываю метод производного класса по указателю static_cast-ed на объект базового класса следующим образом:

class B {};    

class D: public B
{
public:
    void bar() { printf("%d\n", m_i); }
private:
    int m_i;
};

int main()
{
    B b;
    D* d = static_cast<D*>(&b);
    d->bar();
    return 0;
}

Напечатанное значение явно нежелательное, но должно ли это даже компилироваться? Как gcc удается это сделать?

Ответы [ 2 ]

1 голос
/ 05 января 2011

gcc не может гарантировать, что это неверно, за исключением небольшого количества случаев, которые действительно не стоит проверять. Когда вы используете static_cast, вы обещаете компилятору, что знаете, что делаете.

Здесь есть два вида приведений. static_cast, то есть вы говорите компилятору, что указатель на базу - это указатель на производную, и заткнитесь и продолжайте. dynamic_cast, то есть вы просите компилятор проверить, действительно ли этот указатель на базу является указателем на производную. Вы использовали static_cast, поэтому компилятор заткнулся и сделал, как вы сказали.

Edit: Джон точно указал, что в вашей иерархии наследования нет виртуальных функций, для которых вы должны быть запущены из C ++, и dynamic_cast действителен только для виртуальных функций.

0 голосов
/ 05 января 2011

Используя static_cast <>, вы сказали компилятору: «Я знаю, что делаю, что B * на самом деле D *, заткнись и просто делай, что я говорю».

...