2013-11-23 3 views
4

Чистая виртуальная функция не должна иметь тело, но я только что заметил, что следующий код принимается компилятором:Добавление тела к чистой виртуальной/абстрактной функции в C++?

class foo 
{ 
    virtual void dummy() = 0 
    { 
     cout << "hello"; 
    } 
}; 

Итак, почему чистые виртуальные функции разрешают иметь тело? Кроме того, даже если функция имеет тело, класс все еще не может быть создан, почему?

+0

[C40 угловой корпус: вы можете реализовать чистые виртуальные функции в базовом классе] (http://blogs.msdn.com/b/oldnewthing/archive/2013/10/11/10455907.aspx) – GSerg

+2

Я знаю, что удалить = 0 позволит мне создать объект. Но я думаю, это не вопрос, который я задал. Я хотел знать, почему мы не можем создать объект абстрактного класса? –

+0

@DeveshAgrawal '= 0' является объявлением компилятору, что вы не сможете создать экземпляр класса до тех пор, пока вы не переопределите этот метод, совершенно независимо от того, действительно ли этот метод реализован или нет. –

ответ

5

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

Вы можете выполнить чистый виртуальный метод из производного метода (используя явный BaseClass::method()), но все же вы должны обеспечить реализацию.

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

+0

Также обратите внимание, что вам нужно предоставить тело для чистого виртуального деструктора. –

+0

@AndreKostur: Я не думаю, что (с логической точки зрения) чистый виртуальный деструктор имеет смысл. Также не так часто приходится предлагать реализацию базового класса чистого виртуального метода (все, что может быть включено в реализацию базового класса, также может быть, вероятно, более разумным в обычном методе утилиты). Более тонкое семантическое описание комбинации методов присутствует в Common Lisp ... для C++, растягивающего чистый виртуальный, это IMO - плохая идея. – 6502

3

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

Если вам не нужен этот контракт и вы хотите создать экземпляр, не применяйте его к абстрактному классу, то есть удалите = 0.

Если ваша проблема почему бы чисто виртуальные функции имеют тело, в первую очередь, то один хороший пример может быть эта цитата из Эффективное C++ книги Скотт Мейерс:

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

Другим примером является чисто виртуальный деструктор (который также является функцией, кстати):

... 

virtual ~foo() = 0; 

... 

foo::~foo() {} // required! 

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

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