У меня есть абстрактный базовый класс Foo
с абстрактным методом под названием bar
. Я звоню bar
из конструктора Foo
. Я ожидаю, что подклассы, чтобы переопределить bar
(оно абстрактно в конце концов), а затем Foo
вызвать преодолено bar
на каждом экземпляре:Ошибка компоновщика, не объявляя абстрактного метода в абстрактном базовом классе?
class Foo
{
public:
Foo() { bar(); }
virtual void bar() = 0;
}
Однако я получаю сообщение об ошибке:
foo.obj:-1: error: LNK2019: unresolved external symbol "protected: virtual void __cdecl Foo::bar(void)" ([email protected]@@MEAAXXZ) referenced in function "public: __cdecl Foo::Foo(void)" ([email protected]@[email protected])
Такие ошибки компоновщика обычно означают, что я что-то определил, но не объявил об этом (или наоборот), и это, похоже, повторится. Все работает просто отлично, если добавить определение для bar
так:
void Foo::bar() {}
Это предназначена ошибка, или это ошибка в линкере? Если это намеренно, почему? Я не понимаю, почему я не могу назвать абстрактный метод конструктором? Единственная причина, по которой я думаю, заключается в том, что конструктор базового класса получает вызов до того, как будут определены методы подкласса, но я все же не думаю, что должен получить эту ошибку?
Я использую Qt Creator 2.7.0 - Based on Qt 5.0.2 (32 bit)
Как я думал ... Есть ли причина, по которой они добавили/удалили эту функцию? Я уже определил, что 'Foo' имеет абстрактный метод, называемый' bar', почему я не могу его вызвать из конструктора, так как он будет существовать в любом случае? –
@MarkusMeskanen: Боюсь, что ваш вопрос не имеет смысла. Подумайте немного сложнее о том, как работают объекты C++ (особенно конструкция и разрушение при наличии базовых классов) ... нет полезного понятия «функция», как вы утверждаете. –
Извините за недостаток знаний ... Я не могу создать объект типа 'Foo', поэтому у меня должен быть подкласс, который имеет в нем' bar', назовем его 'SubFoo'.Теперь скажем, что 'SubFoo * sf = new SubFoo;', очевидно, будет объектом 'SubFoo', который имеет' bar'. Поэтому я не могу понять, почему я не могу просто вызвать 'bar' из конструктора Foo, поскольку он всегда будет определен. –