Это законный способ реализации нечистых виртуальных функций? - PullRequest
2 голосов
/ 20 ноября 2010

Под «нечистой виртуальной функцией» я подразумеваю чисто виртуальные функции, которые также имеют реализации (как описано в http://www.gotw.ca/gotw/031.htm) для диагностических целей.

Кошерный способ их реализации заключается в следующем:

class Foo
{
public:
    ...
    virtual void Bar() = 0;
};

void Foo::Bar() { assert(false); }

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

В идеале я хотел бы сделать следующее:

class Foo
{
public:
    ...
    virtual void Bar() = 0
    {
        assert(false);
    }
};

, но стандарт C ++ явно запрещает это (раздел 10.4 / 2 в стандарте ISO C ++ 2003).

В качестве альтернативы я подумал о следующем взломе: в заголовке Foo.h:

#ifndef ABSTRACT_METHOD
#define ABSTRACT_METHOD = 0
#endif

class Foo
{
public:
    ...
    virtual void Bar() ABSTRACT_METHOD;
};

, а затем в соответствующем исходном файле Foo.cpp:

#define ABSTRACT_METHOD { assert(false); }

#include "Foo.h"

...

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

Будет ли это допустимо?

Ответы [ 2 ]

4 голосов
/ 20 ноября 2010

Нет, это не законно. Одно правило определения говорит, что класс может иметь несколько определений в программе (из разных единиц перевода), но все эти определения должны состоять из идентичных последовательностей токенов (3.2 / 5). ABSTRACT_METHOD - токен предварительной обработки (до замены макроса), но этого недостаточно.

Таким образом, ваш файл .cpp не может быть корректно использован в той же программе, что и другой файл .cpp, содержащий заголовок.

0 голосов
/ 20 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...