#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];». У вас может быть указатель на него, но вы не можете создать его экземпляр, пока он не будет полностью определен (по достижении закрывающего «}»).