Что особенного в механизме абстрактного класса в C ++? - PullRequest
2 голосов
/ 25 ноября 2010

У меня есть вопрос, который беспокоит меня в течение нескольких дней.

Абстрактный класс - это особый тип класса, который мы не можем создать, верно? (Обозначается / указывается путем предоставления "= 0" хотя бы одному объявлению метода, которое выглядит как запоздалая мысль).

Каковы дополнительные преимущества, которые механизм абстрактного класса приносит в C ++, которых не может достичь «нормальный» базовый класс?

Ответы [ 5 ]

7 голосов
/ 25 ноября 2010

Согласно разделу wikibooks по абстрактным классам :

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

Как уже упоминалось, это способ определения интерфейса , которому должны соответствовать производные классы. Их пример абстрактного класса Vehicle очень уместен: у вас никогда не было бы Vehicle в реальной жизни, у вас был бы Ford Explorer или Toyota Prius, но оба они соответствуют (ради аргумента ) базовый набор функций, который может быть определен как Vehicle. Но вы не можете просто пойти в дилерский центр Vehicle и отогнать Vehicle с участка. Таким образом, вы никогда не захотите иметь возможность создавать и использовать базовый объект Vehicle, для которого вам действительно нужен специализированный производный объект.

2 голосов
/ 25 ноября 2010

Это лучший способ для C ++ определить интерфейс без какой-либо реализации по умолчанию.

C ++ не имеет понятия C # interface.

1 голос
/ 25 ноября 2010

Это эквивалент того, что Java превратила в «интерфейсы».По сути, это означает, что сам класс непригоден для использования - вам нужно переопределить все чистые методы.

Примером является класс CView MFC, который имеет чистый метод OnDraw - базовый CView ничего не делает и выглядит кактакой бесполезный.Вы должны переопределить OnDraw.

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

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

Не думай об этом на уровне класса.

Посмотрите на метод и подумайте, что он должен делать в случае по умолчанию:

virtual std::string getName() const = 0;

Какая будет правильная реализация для этого метода? Нет никого, о чем я могу думать.

Помечая его как «чисто виртуальный», вы гарантируете, что если пользователь когда-либо получит экземпляр класса, производный от вашего интерфейса, то этот метод будет иметь разумное поведение.

Единственный другой способ сделать это - это тело throw NotImplemented("getName");, но тогда вы обнаружите проблему во время выполнения, а не во время компиляции, что не так приятно:)

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

Они используются в качестве базового класса в проекте иерархии классов.
Абстрактные классы используются для определения чистого интерфейса для всех производных классов.
На этапе проектирования абстрактные классы определяют интерфейс для каждой спецификации, а производные классы соответственно реализуют желаемую функциональность.
Также использование абстрактных классов вместо «обычных» классов помогает отделить детали реализации от интерфейса.
Конкретный класс реализует интерфейс, но абстрактный класс определяет его. Вы можете использовать конкретный класс в качестве базового класса в своем проекте, но абстрактные классы не предназначены для непосредственного использования в коде и не могут быть созданы. Они служат прототипом.
Используя «нормальный» класс, как вы сказали, вы должны определить реализацию для всех методов.

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