ошибка: поле ‘дочерние элементы’ имеет неполный тип ‘Узел [2]

#c #c 11 #binary-tree #nodes #treenode

#c #c 11 #двоичное дерево #узлы #treenode

Вопрос:

Когда я запускаю этот код, я получаю ошибку: «Поле ‘Дочерние элементы’ имеет неполный тип ‘Узел[0]'». Я пишу на C и хочу создать класс Node, который создает сам по себе два других объекта Node и так далее, пока не достигнет максимальной глубины. Полная ошибка, которую я получаю:

 18:24:16 **** Incremental Build of configuration Debug for project Tests ****
make all 
Building file: ../main.cpp
Invoking: Cross G   Compiler
g   -std=c  0x -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp:22:17: error: field ‘children’ has incomplete type ‘Node [2]’
  Node children[2];
                 ^
../main.cpp:8:7: note: definition of ‘class Node’ is not complete until the closing brace
 class Node {
       ^
make: *** [main.o] Error 1
subdir.mk:18: recipe for target 'main.o' failed
  

И код:

 #include <iostream>


using namespace std;



class Node {
public:
    int depth;
    bool value;

    Node(bool value, int depth, int maxDepth) {
        this->value = value;
        this->depth = depth;
        if (this->depth < maxDepth) {
            children[2] = {Node(false, this->depth   1, maxDepth), Node(true, this->depth   1, maxDepth)};
        }
    }

private:
    Node children[2];
};


int main() {

    Node tree(false, 0, 1);


    return 0;
}
  

Комментарии:

1. Вы, вероятно, хотите Node *children[2]; (если у вас нет бесконечной доступной памяти).

Ответ №1:

Вы определили класс, Node чтобы он содержал массив Node объектов:

 private:
    Node children[2];
  

Одно Node не может содержать другое Node , поскольку оно должно иметь фиксированный размер, достаточно большой, чтобы содержать его элементы. Оно может содержать указатели на другие Node объекты, и это, вероятно, то, что вам следует использовать в данном случае:

 private:
    Node *children[2];
  

Это означает, что вы должны переписать свое присвоение children массиву (который в его нынешнем виде в любом случае неверен), чтобы он присваивал значения типа Node * :

 // Incorrect:
// children[2] = {Node(false, this->depth   1, maxDepth), Node(true, this->depth   1, maxDepth)};
children[0] = new Node(false, this->depth   1, maxDepth);
children[1] = new Node(true, this->depth   1, maxDepth);
  

Комментарии:

1. Теперь я получаю «ошибка: присвоение массиву из списка инициализаторов». Нужно ли мне что-либо изменить в строке «дочерние элементы [2] = {Узел(false, this-> глубина 1, максимальная глубина), Узел (true, this-> глубина 1, максимальная глубина)};»?

2. @DjSushi Да, конечно, вы это делаете. Если вы измените тип children на массив Node * , то вы должны присвоить элементам этого массива значения типа Node * , а не типа Node . Простым способом сделать это было бы использование new оператора при построении дочерних Node элементов.

3. @DjSushi (Однако обратите внимание, что ваш синтаксис для присвоения children также неверен. У вас есть children[2] = (...) который присваивается (несуществующему) 3-му элементу children массива. Вы должны назначить отдельно для children[0] и children[1] , а не пытаться назначить оба элемента сразу).

Ответ №2:

Реальная проблема заключается в том, что «Узел» не определен в то время, когда компилятор обнаруживает «Дочерние элементы узла[2];». У вас может быть указатель на него, но вы не можете создать его экземпляр, пока он не будет полностью определен (по достижении закрывающего «}»).