Массив типа абстрактного класса в C

#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 является переменной, у многих вызывает затруднения, потому что он не инициализирует нулем весь массив.