Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Наследование от чисто абстрактного класса


Автор: Mechatronic 27.7.2013, 19:03
Здравствуйте.
Имеется чисто абстрактный класс.
Заголовочник
Код

class Parser
{

public:
    virtual int appendByte(uint8_t data);
    virtual void clear();
    virtual ~Parser() = 0;
};

*.cpp файл
Код

Parser::~Parser()
{

}


От него наследуется конкретный класс
Код

class ChildParser : public Parser
{
public:
    ChildParser()
    {

    }

    virtual int appendByte(uint8_t data)
    {

    }

    virtual void clear()
    {

    }
};

Примитивный код для использования этого класса:
Код

int main()
{

    Parser * parser = new ChildParser;
    delete parser;
    return 0;
}

Чего я ожидал: При удалении объекта delete parser будет вызван дестрктор класса ChildParser , затем деструктор родителя Parser .
Не описывать реализации виртуального деструктора родителя нельзя, так как деструктор потомкапостарается вызвать его. Не использовать виртуальный деструктор тоже нельзя - иначе утечет память, выделенная для потомка.
Что вышло: При сборке выводится сообщение : undefined reference to `vtable for Parser'
Как я понял, это значит, что линковщик ищет реализацию виртуальных функций для родительского класса. Но по идее он должен быть чисто абстрактным
Что я сделал не так?

Автор: ChipNDale 28.7.2013, 08:11
Видимо подразумевалось
Код

class Parser
{
public:
    virtual int appendByte(uint8_t data) = 0
    virtual void clear() = 0;
    virtual ~Parser();
};

Автор: Mechatronic 28.7.2013, 13:45
Действительно, так собралось. Не могли бы вы вкратце объяснить для начинающего, в чем я не прав? Я же не инстанцирую родительский класс - зачем это шаманство с виртуальными функциями? Про деструктор ясно - он вызывается из потомка.

Автор: ChipNDale 29.7.2013, 03:01
У метода должно быть либо тело, либо он должен быть чисто виртуальным.
Если не выполняется ни одного условия, значит, невозможно определить адрес метода. В случае с виртуальными методами - какой тогда адрес должен быть в таблице виртуальных функций?

Другая ситуация в случае с кодом из первого поста: допустим, в классе-наследнике виртуальные функции не реализованы. В то же время в нем может не остаться чисто виртуальных функций. Как тогда создавать объекты такого класса?

Автор: Mechatronic 1.8.2013, 11:17
Осознал. Спасибо!

Автор: bsa 1.8.2013, 11:40
Деструктор объекта тоже может быть "чисто виртуальным" (может пригодиться, когда наследование является обязательным условием, но абстрактный класс уже имеет достаточный функционал для самостоятельной работы). Но и в этом случае тело деструктора должно присутствовать:
Код
class MyClass
{
...
   virtual ~MyClass() = 0; //такой класс без наследования инстанцировать уже нельзя
...
};
...
MyClass::~MyClass()
{}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)