Можно ли переопределить виртуальную функцию с помощью чистого спецификатора?

Примечание: я не спрашиваю, разумно ли это делать или это хороший дизайн. Я просто спрашиваю, является ли это четко определенным поведением и соответствуют ли результаты ожидаемым.

Я столкнулся со следующей иерархией классов:

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

struct B: public A
{
    void foo() override 
    {
        std::cout << "B::foo()\n";
    }
};

struct C: public B
{
    virtual void foo() = 0;
};

struct D: public C
{
    void foo() override
    {
        std::cout << "D::foo()\n";
    }
};

int main()
{
    A* d = new D;
    d->foo(); //outputs "D::foo()"
    // A* c = new C; // doesn't compile as expected
}

Этот код хорошо определен? Можно ли переопределить определение с помощью pure-specifier?


person Yksisarvinen    schedule 05.03.2020    source источник
comment
Может быть, вы можете добавить тег [language-lawyer], так как речь идет о спецификации языка?   -  person Martin Morterol    schedule 05.03.2020
comment
Я думаю, вы не можете создать экземпляр C, если он абстрактный. С другой стороны, я бы сказал, что функция перезаписи и перезаписи не является хорошей практикой, в каком случае вы бы использовали это?   -  person Ivan    schedule 05.03.2020
comment
@MartinMorterol Добавлено, спасибо!   -  person Yksisarvinen    schedule 05.03.2020
comment
@Ivan Боюсь, он уже существует в нашем коде, к сожалению, он прошел проверку кода. Мне просто интересно, нормально ли это делать (и что это на самом деле делает).   -  person Yksisarvinen    schedule 05.03.2020
comment
В этом вопросе мне было интересно, действительно ли это действительно для override чистых виртуальных функций, как это сделано здесь, в struct B, и обнаружил, что это действительно хорошая практика - см. stackoverflow.com/ вопросы/46446652/   -  person Odysseus    schedule 05.03.2020
comment
Да, я могу закрыть свой вопрос, проголосовав за закрытие, а затем согласившись с этим голосованием, интересно... Спасибо за ссылки @LanguageLawyer   -  person Yksisarvinen    schedule 06.03.2020


Ответы (1)


[class.abstract/5] текущего проекта стандарта:

[Примечание. Абстрактный класс может быть производным от класса, который не является абстрактным, и чистая виртуальная функция может переопределить виртуальную функцию, которая не является чистой. — конец примечания]

То же самое примечание включено даже в Стандарт C++11. Таким образом, ответ да, это действительно.

person Daniel Langr    schedule 05.03.2020