В чем разница между чисто виртуальным и виртуальным - PullRequest
1 голос
/ 20 января 2011

Я модифицирую код, чтобы класс прародителя был чисто виртуальным, который включает в себя чисто виртуальную версию функции XYZ;тогдашний родительский класс объявляет XYS как виртуальный, и у него есть реализация для него.Затем дочерний класс объявляет XYZ как обычную функцию с реализацией, отличной от реализации parent1, что само по себе меня смущает).Когда я вызываю функцию XYZ из другого объекта, какая реализация выполняется?родитель один или ребенок один?Спасибо

Ответы [ 7 ]

5 голосов
/ 20 января 2011

Когда я вызываю функцию XYZ из другого объекта, какая реализация выполняется? родитель или ребенок один?

Давайте выясним:

struct A {
  virtual void f() = 0;
};

struct B : A {
  virtual void f() { cout << "B::f\n"; }
};

struct C : B {
  virtual void f() { cout << "C::f\n"; }
};

int main() {
  C().f();
  return 0;
}
3 голосов
/ 20 января 2011

Чистые виртуальные функции не нуждаются в определении (в отличие от виртуальных функций), и они делают свой класс абстрактным. Абстрактные классы не могут иметь объект, созданный из, за ​​исключением случаев, когда они действуют как объект базового класса.

Ваша путаница связана с наличием или отсутствием ключевого слова virtual. Если функция объявлена ​​virtual в базовом классе, то функция производного класса, независимо от того, введено или нет ключевое слово virtual, автоматически станет virtual, если она имеет то же имя, типы параметров и константу.

Таким образом, если вы вызовете XYZ для grandparent* или parent*, который фактически указывает на объект child, то будет выполнен XYZ объекта child.

2 голосов
/ 20 января 2011

Чистая виртуальная функция просто означает, что ни один класс с чистой виртуальной функцией не может быть создан. Как только родительский класс переопределяет его, он просто становится обычной виртуальной функцией. После того, как функция была объявлена ​​виртуальной в базовом классе, она всегда виртуальная, независимо от того, определяет ли наследующий класс ее как виртуальную.

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

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

В случае виртуальной функции, если вы вызываете xyz для объекта дочернего класса, всегда будет выполняться дочерняя версия xyz (Child::xyz()).

Это не относится к не виртуальным переопределенным методам.Тогда, если бы у вас был указатель Parent* ptr = &child, ptr>xyz() фактически выполнил бы Parent::xyz().Но в вашем случае это Child::xyz().Вот почему вы используете ключевое слово virtual.

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

Виртуальная функция - это та, которая может быть переопределена в производном классе.

Чистая виртуальная функция - это та, которая вообще не имеет реализации, и поэтому ДОЛЖНА быть переопределена в производном классе.

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

0 голосов
/ 20 января 2011
class sample
{
public:
   virtual void fun(); //virtual function
   virtual void sun()=0; //pure virtual function
};

Чистая виртуальная функция объявляется путем присвоения 0, как сделано выше.Определение виртуальных функций pure необязательно , а определение виртуальных функций обязательно , в противном случае не будет компилироваться.Кроме того, вы не можете создать экземпляр класса, который определяет даже одну pure виртуальную функцию.

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

Чистая виртуальная функция обычно не имеет реализации и создает «абстрактность» класса.

Компилятор не позволит вам создать экземпляр класса, который является абстрактным.Любой класс, производный от этого класса, остается абстрактным, если не реализованы все чистые виртуальные функции, которые он наследует (и он не добавляет никаких новых).Такой класс называется конкретным.

Обратите внимание, что чисто виртуальной функции может быть предоставлена ​​реализация (хотя она не может быть встроенной по причинам синтаксиса).Кроме того, у вас может быть чистый виртуальный деструктор, и тогда ему нужно дать реализацию (даже если она пустую).

Вы указываете чисто виртуальную функцию, добавляя = 0 в конце, таким образом:

virtual void foo(); // not pure
virtual void bar() = 0; // pure virtual
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...