2010-04-19 4 views
10

У меня есть вопрос, здесь два класса ниже:поведения виртуальной функции в C++

class Base{ 
     public: 
      virtual void toString();  // generic implementation 
    } 

    class Derive : public Base{ 
     public: 
      (virtual) void toString(); // specific implementation 
    } 

Возникает вопрос:

  • Если я хочу подкласс класса Выведите выполняет polymophism с использованием указатель типа База, является ли ключевым словом виртуальный в скобке?

  • Если ответ нет, в чем разница между функцией члена ToString класса Выведите и без виртуального?

+1

Это необязательно, но некоторые считают, что вопрос хорошего стиля должен быть явным о переопределении функций-членов. – pmr

ответ

13

C++ 03 §10.3/2:

Если виртуальная функция-член является VF объявлен в базовом классе и в классе Derived , полученные прямо или косвенно из базы, член функции VF с тем же именем и же Список параметров в качестве Base :: vf: объявлен, то Производный :: vf также является виртуальным (независимо от того, объявлен он ) и он переопределяет База :: vf.

+2

+1 для цитирования фактической ссылки –

10

Это ключевое слово строго необязательно и не имеет никакого значения.

+11

Это не имеет никакого значения для компилятора. Для читателя-человека это может улучшить читаемость. Я всегда явно утверждаю виртуальный на всех уровнях наследования. –

7

Свойство virtual наследуется от базового класса и предполагается присутствовать, даже если вы его не вводите.

1

Компилятор уже знает из «виртуального» ключевого слова в базовом классе, что toString является виртуальным методом. Не нужно повторять это.

+4

Можно добавить, что это может повлиять на читателя. – sbi

1

Функция как виртуальная виртуальная виртуальная.

Так что в любом случае, если ключевое слово virtual не используется в последующих классах, это не препятствует тому, чтобы функция/метод была «виртуальной», то есть переопределена. Таким образом, следующее руководство может помочь с точкой зрения из-развития команды: -

  • Если функция/метод должен быть переопределен , всегда используйте «виртуального» ключевое слова. Это особенно относится к true при использовании в интерфейсе/базе классов.
  • Если производный класс должен быть суб-классифицироваться далее в явной форме состояние «виртуальное» ключевое слово для каждого функции/метода, который может быть переопределен .
  • Если функция/метод в производном классе не должен быть к югу классифицироваться снова, то ключевым слово «виртуального» должны быть прокомментированы , указывающими, что функция/метод был преодолен, но нет нет другие классы, которые переопределяют его . Это, конечно же, не мешает кому-то переопределить в производном классе , если класс не является окончательным (не выводимым), но он указывает, что метод не должен быть переопределен . Ex: /*virtual*/ void someFunc();
+0

Для случая «всегда быть переопределенным», возможно, потребуется добавить и чистый спецификатор. – Myke

+0

Я думаю, что там должна быть запятая между «переопределенными» и «всегда». т. е. «всегда использовать ключевое слово« virtual », а не« всегда переопределяться ». –

+0

@Ben: Вы правы, Thnx. – Abhay

0

Это не имеет значения для компилятора ли не поставить вас в виртуального ключевым слова на производные версии функции.

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

0

Это вопрос хорошего стиля, и пользователь-программист знает, что происходит. В C++ 0x вы можете использовать [[переопределить]], чтобы сделать его более явным и видимым. Вы можете использовать [[base_check]], чтобы принудительно использовать [[переопределить]].

Если вы этого не хотите или не можете сделать, просто используйте ключевое слово virtual.

Если вы вывели без виртуального toString, и вы передали экземпляр Derive back to Base, вызов toString() фактически вызовет функцию base toString(), поскольку, насколько известно, это экземпляр Base.

Смежные вопросы