Почему мы не можем создать объекты для абстрактного класса в C++?

Я знаю, что это не позволяется в C++, но почему? Что, если бы было позволено, каковы проблемы были бы?

7
задан Moeb 19 January 2010 в 06:07
поделиться

7 ответов

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

сами функции не содержат памяти в классе. Следующий класс:

struct dumb_class
{
    void foo(){}
    void bar(){}
    void baz(){}
    // .. for all eternity

    int i;
};

имеет размер int . Независимо от того, сколько функций, которые вы когда-либо имеете, этот класс займет только пространство, необходимое для работы на INT . Когда вы вызываете функцию в этом классе, компилятор будет передавать вам указатель на место, где хранятся данные в классе; Это указатель .

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

Виртуальные функции разные. Стандарт C ++ работает не мандат, как следует поведение виртуальных функций, только то, что должно быть, которое должно быть. Как правило, реализации используют то, что называется виртуальной таблицей или VTable для коротких. VTable - это таблица указателей функций, которые, как и нормальные функции, только один раз выделяется.

Возьмите этот класс и предположим, что наш реализатор использует VTable:

struct base { virtual void foo(void); };
struct derived { virtual void foo(void); };

Компилятор должен будет делать два VTTable, один для базы и один для получения. Они будут выглядеть что-то подобное:

typedef /* some generic function pointer type */ func_ptr;

func_ptr __baseTable[] = {&base::foo}; 
func_ptr __derivedTable[] = {&derived::foo}; 

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

derived d;
base* b = &d;
b->foo();

при выполнении последней строки, он идет на правильный стол ( __ derivedtable в этом случае), переходит к правильному индексу (0 в этом случае) и вызывает эту функцию. Как видите, что в конечном итоге вызовут , полученных :: foo , что именно то, что должно произойти.

Примечание. Для позже это то же самое, что и делает , полученных :: foo (b) , прохождение b как этот указатель .

Итак, когда присутствуют виртуальные методы, класс размера увеличится на один указатель (указатель на vTable.) Несколько наследство меняется, но в основном это то же самое. Вы можете получить более подробную информацию о C ++ - FAQ .

Теперь на ваш вопрос. У меня есть:

struct base { virtual void foo(void) = 0; }; // notice the = 0
struct derived { virtual void foo(void); };

и База :: Foo не имеет реализации. Это делает базы :: Foo Чистая абстрактная функция. Итак, если бы я назвал это, как выше:

derived d;
base* b = &d;
base::foo(b);

Какое поведение мы должны ожидать? Будучи чистым виртуальным методом, базой :: foo даже не существует. Приведенный выше код является неопределенным поведением и может сделать что-либо от ничего не для разбивающейся, с чем-либо между ними. (Или хуже.)

Подумайте о том, что представляет чистую абстрактную функцию. Помните, функции несут никаких данных, они описывают только, как манипулировать данными. Чистая абстрактная функция говорит: «Я хочу позвонить в этот метод и иметь свои данные о манипулировании. Как вы это делаете для вас».

Так что, когда вы говорите: «Ну, давайте назовем абстрактный метод», Отправить на вышеуказанное с: «До меня? Нет, ты это делаешь». к которому он ответит "@ # ^ @ # ^". Это просто не имеет смысла сказать кому-то, кто говорит: «Делай это», «нет».

Чтобы ответить на ваш вопрос напрямую:

«Почему мы не можем создать объект для абстрактного класса?»

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

25
ответ дан 6 December 2019 в 05:06
поделиться

Проблема в том, что это просто это:

  • Что должна делать программа, когда вызывается аннотация метод ?
  • и еще хуже: что следует вернуть для Функция ?

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

5
ответ дан 6 December 2019 в 05:06
поделиться

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

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

3
ответ дан 6 December 2019 в 05:06
поделиться

Потому что логически это не имеет никакого смысла.

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

Мой первый пример был шахматной игрой:
Игра имеет много кусочков разных типов (король, королева, пешка ... и т. Д.).

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

3
ответ дан 6 December 2019 в 05:06
поделиться

Абстрактные классы не мгновенные по определению . Они требуют, чтобы быть получены, бетонные классы. Что еще может быть абстрактным классом, если бы у него не было чистых виртуальных (невыполненных) функций?

2
ответ дан 6 December 2019 в 05:06
поделиться

Абстрактные классы были бы довольно бесполезны, потому что вы бы увидели гораздо больше "чистой виртуальной функции, называемой". :)

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

0
ответ дан 6 December 2019 в 05:06
поделиться
-

Это тот же класс вопросов, что и почему я не могу изменить значение переменных Const, почему я не могу получить доступ к членам частного класса из других классов или почему я не могу переопределить финал методы.

Потому что это цель этих ключевых слов, чтобы предотвратить это. Потому что автор Кода, который считается таким опасным, нежелательным или просто невозможным из-за некоторых абстрактных причин, таких как отсутствие необходимых функций, которые необходимо добавить удельными детскими классами. На самом деле вы не можете создать экземпляр, потому что класс является виртуальным. Именно в том, что неспособность создавать класс определять его как виртуальный (и если класс, который не может быть создан, не виртуален, это ошибка. То же самое идет другим способом, если экземпляр данного класса имеет смысл, оно не должно быть отмечен как виртуальный)

0
ответ дан 6 December 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: