Почему этот метод не виртуальный, как я ожидал? - PullRequest
2 голосов
/ 30 августа 2010

Я хочу спросить, что происходит, когда я использую виртуальные функции без указателей? например:

#include <iostream>
using namespace std;
class Parent
{
 public:
   Parent(int i) { }
   virtual void f() { cout<<"Parent"<<endl; }
};

class Child : public Parent
{
 public:
   Child(int i) : Parent(i) { }
   virtual void f() { Parent::f(); cout<<" Child"<<endl; }
};

int main()
{
    Parent a(2);
    Parent b = Child(2);
    a.f();
    b.f();
    return 0;
}

^^ Почему это не работает? Где я могу найти информацию о том, как на самом деле работают виртуальные методы?

Ответы [ 3 ]

14 голосов
/ 30 августа 2010

Этот эффект называется «нарезка».

Parent b = Child(2); // initializes a new Parent object using part of Child obj

В C ++ динамический тип может отличаться от статического типа только для ссылок или указателей. У вас есть прямой объект. Итак, ваше подозрение было по существу правильным.

4 голосов
/ 30 августа 2010

Попробуйте следующее:

std::auto_ptr<Parent> b = new Child(2);

В своем коде вы копируете часть объекта Child в b. Это так называемое нарезка объектов .

1 голос
/ 30 августа 2010

Механизм виртуальных функций включается, только если виртуальная функция вызывается либо с помощью соответствующей ссылки, либо с помощью соответствующего указателя.Обратите внимание, что механизм вызова виртуальной функции подавляется в конструкторе / деструкторе или при использовании оператора ::.

Если код такой, как показано ниже, механизм виртуальной функции будет включен.

Child c;
Parent &a = c;
a.f();

Без указателей вызов статически связан, даже если это вызов виртуальной функции.

РЕДАКТИРОВАТЬ 2:

$ 10,3 / 6 - [Примечание: интерпретация вызоваВиртуальная функция зависит от типа объекта, для которого она вызывается (динамический тип), тогда как интерпретация вызова не виртуальной функции-члена зависит только от типа указателя или ссылки, обозначающей этот объект (статический тип) (5.2.2).]

...