Когда возникает ошибка Incomplete Type в C++

Может ли кто-нибудь сказать мне, когда компилятор С++ выдает «ошибку неполного типа»?

Примечание. Я намеренно оставил этот вопрос немного открытым, чтобы я мог сам отлаживать свой код.


person Nickal    schedule 07.07.2017    source источник
comment
Тип, возможно, cv-квалифицированный, который не определен или недействителен, является неполным типом. Объект не должен быть определен как неполный тип. И нет, это не лучший формат вопроса   -  person Passer By    schedule 07.07.2017
comment
См. это, например, -itse" title="неполный тип в классе, который имеет член того же типа, что и сам класс"> stackoverflow.com/questions/6349822/   -  person Abdulkadir Dalga    schedule 07.07.2017
comment
@PasserBy У меня есть кто-то, кто ответил на мой вопрос и помог мне найти ошибку. Он был более полезным, чем ты. Тем не менее, спасибо.   -  person Nickal    schedule 07.07.2017


Ответы (4)


Обычно это происходит, когда компилятор видел предварительное объявление, но не видел полного определения этого типа, в то время как этот тип где-то используется. Например:

class A;

class B { A a; };

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

Однако, когда вы просто используете указатель на такое предварительное объявление, никаких жалоб не возникнет, поскольку размер указателя на класс всегда известен. Так:

class A;
class B {
   A *a;
   std::shared_ptr<A> aPtr;
};

Если вы спросите, что может быть не так в конкретном приложении или библиотеке, когда возникает эта ошибка: обычно это происходит, когда включен заголовок, содержащий предварительное объявление, но полное определение еще не найдено. Решение вполне очевидное: включите также заголовок, который дает вам доступ к полному типу. Иногда вы также можете просто не использовать пространство имен или использовать неправильное пространство имен для типа, и вместо этого вам нужно исправить это.

person Mike Lischke    schedule 07.07.2017
comment
На самом деле в моем случае это исходит из файла заголовка библиотеки PCL ‹window.h›. Поскольку это библиотечный файл, в файле как таковом не должно быть ошибок. Должно быть что-то еще, что приводит к этой ошибке. - person Nickal; 07.07.2017
comment
это происходит, когда заголовочные файлы включены в проект, но библиотека не подключена??? - person Nickal; 07.07.2017
comment
Нет, компиляция и компоновка — это два разных шага. Сначала компилятор должен создать объектный код (и поэтому должен знать все используемые типы), затем компоновщик связывает их все вместе в окончательные двоичные файлы. - person Mike Lischke; 07.07.2017
comment
Спасибо. Редактирование было очень полезным. Я включил файл, содержащий полное определение, прежде чем включать заголовок. Это сработало. - person Nickal; 07.07.2017

Это происходит, когда мы пытаемся использовать класс/объект или его методы, которые еще не определены. Например

class A;
class B {
    class A obj;
}

or

class A;
class B {
    class A *obj;
    B() {   
           obj->some_method();
        }

Чтобы решить эту проблему, A должен быть определен первым или его полное объявление должно быть задано (лучше всего сделать это в заголовочном файле), а все методы обоих классов должны быть определены позже (лучше всего сделать это в другом файле). ).

class A {
    //definition
}
class B {
class A obj;
}
person calceamenta    schedule 07.11.2018

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

template<typename T>
class
{
  foo a;
  foo b;
};
function(T a,int b)
{

 . . . . .

}

И это создало проблемы, так как определение шаблона связано с классом, в этом случае в списке параметров функции возникает ошибка T is not defined, а также incomplete type is not allowed. Если вам нужно использовать шаблон для нескольких сущностей, вы должны повторно использовать этот оператор перед определением этих сущностей:

template<typename T>
person Abhishek Agarwal    schedule 21.06.2019

Это также происходит, когда вы используете предварительное объявление с std::unique_ptr (например, для реализации идиомы PIMPL) в своем классе с деструктором по умолчанию, что приводит к такой проблеме.

Это хорошо объяснено здесь: Предварительное объявление с unique_ptr?

person Mykola Khyliuk    schedule 19.08.2020