Как я могу использовать класс до его определения? - PullRequest
7 голосов
/ 25 мая 2010
class Node
{
    string name;
    Node previous;
};

 Error: Node::previous uses "Node" which is being defined.

Как мне заставить это работать в C ++? Это работает в C #.

EDIT:

Почему Node* previous работает?

Ответы [ 6 ]

10 голосов
/ 25 мая 2010

Используйте указатели. Node* previous; решит проблему.

Делая это сейчас, вы на самом деле пытаетесь сделать свой класс бесконечно большим.

8 голосов
/ 25 мая 2010

Используйте указатель или ссылку.

Например:

Node* previous;

Единственное ограничение заключается в том, что класс не может иметь собственное поле, вероятно, по причине конструкции. Подумайте об этом, если в каждой коробке есть еще одна коробка, как бы вы получили конечное количество коробок?

Если я не ошибаюсь, C # использует ссылки только для типов классов (как и Java), поэтому вы используете там ссылку, просто не видя ее.

5 голосов
/ 25 мая 2010

Для редактирования подумайте, ваш node содержит еще один node, который содержит еще один внутри. Таким образом, у вас есть бесконечная последовательность узлов, содержащихся друг в друге. То, что вы хотите, это указатель на место, где хранится следующий node. Поэтому вы должны изменить его на Node*.

2 голосов
/ 26 мая 2010

Думайте об объекте Car "в реальном мире". Он может содержать ссылку на другой объект Car через номер VIN. Он может даже содержать ссылку на себя или на значение VIN 0 (NULL или NO CAR).

Но что, если вы буквально хотели, чтобы каждый объект автомобиля находился внутри другого объекта автомобиля? Как это будет работать? Какой объект Car будет содержать содержащийся объект Car?

Java и C # на самом деле не помещают объект в содержащий класс, а ссылаются на объект. Такие языки, как C ++, позволяют вам указать, есть ли ОБЪЕКТ, содержащийся в классе, ССЫЛКА на другой ОБЪЕКТ, содержащийся в классе, или даже указатель на другой ОБЪЕКТ, содержащийся в классе:

class Car
{
   Engine engine;  // Car CONTAINS an Engine object
};

class Car
{
   Engine &engine;  // Car contains a REFERENCE to an Engine object
};

class Car
{
  Engine *pEngine;  // Car contains a POINTER to an Engine object
};

В конце концов вы дойдете до того, что знаете, когда и зачем использовать первое, второе или третье, но это совсем другой вопрос.

2 голосов
/ 25 мая 2010

В C # объявление previous как это дает вам ссылку. В C ++ объявление previous таким образом дает вам объект, встроенный в каждый объект класса Node.

В объект не может быть встроен объект того же класса , рекурсивно. previous.name должен был бы существовать (и иметь выделенное ему хранилище), как и previous.previous.name, и так далее бесконечно, все в одном выделении памяти. Размер объекта Node должен быть как минимум равным размеру объекта string плюс размер объекта Node (что невозможно, поскольку string больше 0 байт). И другие подобные противоречия.

Как говорят другие, используйте указатель: Node *previous или ссылку Node &previous. Или std::deque<std::string>; -)

Возможно, вы хотели бы знать, что C ++ отличается от C # другими способами, которые испортят ваш день, если вы попытаетесь написать односвязный список путем переноса кода C #. Нет мусора, например. Вы не можете написать правильный код C ++ без понимания объектной модели C ++.

1 голос
/ 25 мая 2010

Разве Node не должен быть указателем?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...