Может ли чистый абстрактный класс содержать статические константы, статические методы или не виртуальные деструкторы?

Это чистый абстрактный класс?

class C
{
public:
    static const std::string S;
    C() {}
    virtual ~C() {}
    virtual void v() = 0;
}

Я считаю, что это не так, следуя этому определению из WikiBooks:

Чистый абстрактный класс имеет только абстрактные функции-члены и не содержит данных или конкретных функций-членов.

Он не может быть чисто абстрактным, поскольку не имеет только абстрактных функций-членов:

  1. У него есть виртуальный деструктор, который является функцией-членом, но не абстрактным. Это не чистый деструктор. Обратите внимание, что "абстрактный метод" и "чисто виртуальная функция" - это одно и то же, а термины "метод" и "функция" являются синонимами.
  2. У него есть атрибут S, который представляет данные.

Теперь мои учителя утверждают, что это чистый абстрактный класс, потому что:

Константы, включенные в чистый виртуальный класс, не считаются атрибутами. Они являются неизменными элементами класса и поэтому не нарушают его абстрактность. То же самое относится и к статическим методам.

Ответ 1

Подводя комментарии выше:

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

(18 октября, 15:15 13:46 UTC от Ульриха Экхардта)

Стандарт С++ вообще не определяет термин "чистый абстрактный класс", поэтому можно утверждать, что чистые абстрактные классы не существуют в С++; или, альтернативно, чтобы вы могли объявить конкретную конструкцию С++ "чистым абстрактным классом", и это прекрасно, пока другие участники обсуждения согласятся использовать ваше определение. Просто попросите своего учителя указать точное определение термина, с которым он или она трудится; ничего похожего на аргумент определения, чтобы получить один поток соков.

(18 октября, 15:15 14:07 UTC Игоря Тандетника)

Предоставленное вами определение бесполезно в контексте С++. Во-первых, С++ не имеет абстрактных функций-членов (имеет чисто виртуальные). Класс С++ (почти) всегда имеет конструктор (возможно, неявный), который не может быть виртуальным, поэтому, если вы настаиваете на подсчете конструктора как функции-члена, то класс С++ не будет соответствовать определению. Что касается статических элементов данных, то даже те языки, которые имеют явное понятие абстрактного класса (например, Java), не запрещают их. Дело в том, что класс не должен иметь данные для каждого экземпляра.

(19 октября, 15:00 02:03 UTC от Игоря Тандетника)

Ответ 2

Абстрактный класс - это класс, в котором есть объявление, но нет определения

Чистый абстрактный класс в C++ также рассматривается как интерфейс.

Следовательно, любые константные объявления не нарушают чистоту абстрактности классов. В IDL вы можете объявить константы внутри и снаружи интерфейсов.

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

class C
{
public:
    const std::string S = "Message";
    virtual ~C() = 0;
    virtual void V() = 0;
};

Ответ 3

Стандарт C++ не определяет, что такое "чисто абстрактный" класс, и нет общепринятого независимого от языка определения, которое одинаково подходит всем языкам.

Определение 1, которое вы цитируете, не имеет большого смысла для меня в контексте C++. То, что утверждают ваши учителя, больше соответствует языковому дизайну. Используйте любое определение, удобное и необходимое. В любом случае само понятие совсем не важно.

Ответ 4

Определение из WikiBooks определенно происходит от интерфейсов java. Последний был создан, чтобы обойти ограничение правила единого наследования. Классы Java могут иметь один суперкласс и реализовывать несколько интерфейсов.

Интерфейс Java имеет:

  1. абстрактные методы
  2. константы
  3. статические переменные и методы
  4. методы по умолчанию.

Он не имеет конструкторов, переменные, ни this указатели. Стандартные или статические методы могут обращаться только к статическим переменным.

Использование выше в качестве шаблона, ваш пример класса не вписывается в определение, потому что он определяет конструктор. Интерфейсы не имеют конструкторов. Таким образом, класс с конструктором только по умолчанию будет соответствовать. В Java нет понятия деструкторов, поэтому не имеет значения, есть ли у вас деструктор или нет в вашем случае.

В C++ нет необходимости обрабатывать интерфейсы типа Java, потому что он поддерживает множественное наследование. Классы могут иметь произвольные абстрактные функции.

У Java также есть понятие abstract классов. Это классы, которые имеют один или несколько абстрактных функций-членов. Они очень похожи на классы C++ с абстрактными функциями, за исключением правил одиночного наследования. В Java также нет понятия pure abstract классов (если не говорить об интерфейсах).