#c #abstract-class
#c #абстрактный класс
Вопрос:
#include <iostream>
class test {
virtual void func() = 0;
};
int main(){
test t[] = {};
return 0;
}
Приведенный выше код сгенерирует эту ошибку во время компиляции:
error: array of abstract class type 'test'
Однако он компилируется, если вместо него используется массив указателей:
test* t[] = {};
Это потому, что чисто виртуальные функции еще не имеют размера, поэтому компилятор
не знает, сколько места он должен выделить? но указатели имеют размер, так что это нормально?
Комментарии:
1. Когда вы создаете экземпляр массива, вы создаете экземпляр всех элементов массива. Если вы не можете создать экземпляр элементов, компилятор предупреждает вас. Я вижу, что вы здесь делаете, пустой массив, но компилятору явно все равно. Он не может создать массив
test
.2. @Dan,
test t[] = {};
не стал бы компилироваться, даже если бы это был не абстрактный класс, потому что размер должен быть предоставлен, и если это так, скажемtest t[5] = {};
, компилятор вызовет конструкторы этого класса для каждого элемента объявленного массива, поскольку это абстрактный класс, он не может этого сделать.3. @anastaciu Я тебя не поправлял. Ваша интерпретация верна. Я имел в виду комментарий как предупреждение спрашивающему о расширениях компилятора, требующих собственной документации.
4. @user4581301, Да, я знаю, я пинговал тебя, чтобы узнать, знаешь ли ты, почему это происходит, это становится еще более странным, если я использую,
-pedantic
не-pedantic-errors
обращай внимания, тогда не удается скомпилировать с ожидаемымerror: zero-size array ‘t’
.5. Я подозреваю, что g допускает это из-за гибких элементов массива в C.
Ответ №1:
Это потому, что …
Это потому, что абстрактные классы не могут быть созданы и, как таковые, не может быть массивов таких типов. Это просто не разрешено в языке.
Указатели не являются абстрактными классами (и даже не являются классами), независимо от типа, на который они указывают.
test* t[] = {};
однако, несмотря на это, неправильно сформирован, поскольку переменная массива не может иметь нулевых элементов.
Комментарии:
1. итак, если они являются указателями, то компилятор не будет вызывать конструкторы, поскольку они просто указатели?
2. @Dan Да. У указателей нет конструкторов.
3. Я только что сделал
int t[] = {};
, и он отлично компилируется.4. @Dan Независимо от этого, он неверно сформирован. Если компилятор не диагностирует это, значит, компилятор не соответствует стандарту C . И другим, соответствующим стандарту компиляторам, разрешено не компилировать его нормально.
5. @Dan Вам нужно будет проверить документацию для вашего компилятора, чтобы узнать, чего ожидает компилятор и как он будет себя вести. Я знаю, что расширения массива g приводят ко многим интересным различиям. Например,
int arr[n] = {0};
, гдеn
является переменной, у многих вызывает затруднения, потому что он не инициализирует нулем весь массив.