Почему мы не можем создать экземпляр абстрактного класса? - PullRequest
10 голосов
/ 27 февраля 2011

Я нашел во многих местах, что:

  • Абстрактный класс - это класс, который предполагается использовать в качестве базового класса.
  • Абстрактный класс - это класс, который имеет хотя бы одну Чистую Виртуальную Функцию.

Но одна вещь, которая всегда поражает меня - почему мы не можем создать экземпляр абстрактного класса? Во многих местах в Интернете говорят, что нет никакого смысла создавать экземпляр, или некоторые говорят, что они должны использоваться в качестве базовых классов. Но почему ошибочно создавать экземпляр абстрактного класса?

Ответы [ 7 ]

15 голосов
/ 27 февраля 2011

Ваш void bar()=0; недействителен - нотацию =0 можно использовать только с виртуальными функциями.

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

Например, рассмотрите драйверы устройств.У нас может быть драйвер для абстрактного устройства хранения.Мы определяем некоторые возможности для этого устройства, такие как чтение и запись данных.Этот абстрактный класс дает любому коду, который хочет читать / записывать данные, возможность работать с конкретным классом, производным от этого абстрактного класса.

Мы не можем просто создать экземпляр нашего абстрактного устройства хранения.Вместо этого нам нужен конкретный объект, такой как флэш-накопитель, дисковод и т. Д., Для чтения / записи.Конкретный класс необходим, потому что нам нужен код, специфичный для реального устройства, для выполнения команд, которые мы определили в нашей абстрактной базе.У нашего абстрактного класса хранения только чтение или запись, но do чтение или запись, нам нужен драйвер для конкретного устройства.Кто-то знает, как разговаривать с жестким диском SATA, а кто-то знает, как разговаривать с флэш-накопителем USB, а третий знает, как читать с SD-карты или записывать на нее.Мы не можем , однако, просто скажем «Я собираюсь создать абстрактное устройство хранения» и поговорим с ним, не определяя фактический код, который будет переводить команду «записи» в (например)правильные сигналы, передаваемые через SATA, USB, Firewire и т. д., для передачи данных на реальный диск.

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

11 голосов
/ 27 февраля 2011

Абстрактный класс представляет собой нечто, недостаточно конкретное для создания экземпляра. Например, что если кто-то попросит вас создать автомобиль? Вы должны спросить, "что за автомобиль?" Вы не знаете, создать ли автомобиль, сани или космический челнок. Там нет такого объекта, как «транспортное средство». Тем не менее, «средство передвижения» - это полезная абстракция, которая может использоваться для группировки объектов, указывая на общее поведение среди них. Вот для чего нужны абстрактные классы.

4 голосов
/ 27 февраля 2011

Абстрактный класс - это больше, чем интерфейс. Это может иметь данные членов. Он может иметь функции-члены, которые не являются чисто виртуальными или вообще не виртуальными. Даже чисто виртуальная функция может иметь тело, обеспечивающее реализацию по умолчанию. Так что речь идет не о физической невозможности создания абстрактного класса.

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

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

3 голосов
/ 27 февраля 2011

В этом весь смысл абстрактного класса: некоторые детали должны быть предоставлены разработчиком.

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

2 голосов
/ 27 февраля 2011

Причина, по которой абстрактный класс не может быть создан, заключается в следующем: что вы делаете, если выполняете чисто виртуальную функцию? Это было бы серьезной ошибкой, и лучше ее уловить во время компиляции, чем во время выполнения.

1 голос
/ 27 февраля 2011

В абстрактном классе определение метода не дается, предоставляется только структура.Если бы мы могли создать экземпляр абстрактного класса и вызвать этот метод, это будет огромный беспорядок.Абстрактный класс используется для поддержки шаблона проектирования кода.

0 голосов
/ 10 мая 2019

Только Чак Норрис может создать экземпляр абстрактного класса.

https://api.chucknorris.io/jokes/ye0_hnd3rgq68e_pfvsqqg

...