Дополнительно
Почему связанные списки использовать указатели вместо сохранения узлов внутри узлов
Я'вэ работал с связанные списки, прежде чем широко в Java, но я'м очень новой для C++. Я использовал этот класс узла, который был дан мне в проект, просто отлично
class Node
{
public:
Node(int data);
int m_data;
Node *m_next;
};
но у меня один вопрос, что это'т очень хорошо ответил. Почему это надо использовать
Node *m_next;
чтобы он указывал на следующий узел в списке вместо
Node m_next;
Я понимаю, что лучше использовать указатель версию; Я'м не собираюсь спорить с фактами, но я Дон'т знаю, почему это'ы лучше. У меня не так, внятного ответа о том, как лучше указатель для выделения памяти, и я был интересно, если кто может помочь мне понять, что лучше.
120
10
Это's не просто лучше, это'ы единственно возможным способом.
Если вы сохранили "узел" объект внутри себя, что бы оператор sizeof(узел)
быть? Это будет
оператор sizeof(тип int) + оператор sizeof(узел), которая будет равнаоператор sizeof(тип int) + (оператор sizeof(тип int) + оператор sizeof(узел)), которая будет равна
оператор sizeof(тип int) + (оператор sizeof(тип int) + (оператор sizeof(тип int) + оператор sizeof(узел))) и т. д. до бесконечности.Объект, как, что может'т существуют. Это'ы невозможно.
В Java
хранит указатель на другой узел. Вы Don't есть выбор об этом. В C++
означает то же самое. Разница в том, что в C++ вы можете хранить объект, а не указатель на него. Что's, почему вы должны сказать, вы хотите, чтобы указатель. В C++:
значит магазин узел прямо здесь (и, что очевидно, может't работа для список - вы в конечном итоге с рекурсивно определенной структурой).
C++ это не JAVA. Когда вы пишете
в Java, это все равно, что писать
в языке C++. В Java, указатель подразумевается, в C++ это явно. Если вы пишете
в C++, вы помещаете экземпляр
узел
сейчас внутри объекта, который вы определяете. Она всегда есть и не может быть опущен, она не может быть распределена с "новым" и он не может быть удален. Такого эффекта невозможно достичь в Java, и это совершенно отличается от того, что Ява делает один и тот же синтаксис.Вы используете указатель, в противном случае ваш код:
...бы не компиляции, поскольку компилятор не может вычислить размер "узел". Это потому, что это зависит от самого усилителя;amp; mdash; не значит, компилятор не может решить, сколько памяти она будет потреблять.
Последний (
узла m_next
) должны содержать узел. Это не'т указать на это. И тогда не было бы никаких связывающих элементов.Подход, который вы описали совместима не только с C++, но и С [(в основном) подмножество языка C][1]. Научиться разрабатывать на C-стиль связанного списка является хорошим способом, чтобы представить себя низкоуровневые методы программирования (например, ручного управления памятью), но это вообще не рекомендуется для современной разработке на C++.
Ниже я реализовал четыре вариации на том, как управлять список элементов в C++.
raw_pointer_demo
использует тот же подход как у тебя -- ручное управление памяти, необходимой при использовании сырых указателей. Использование C++ здесь только для [синтаксического сахара][2], и применяемые подходы несовместимы с языка Си.std_list_demo
использует стандартные библиотеки ["список"] [4] контейнер. Это показывает, насколько легче вам, если вы опираетесь на существующие библиотеки, а не свертывать ваши собственные.std_vector_demo
использует стандартные библиотеки [вектор
][5] контейнер. Это управляет списком хранение в одном непрерывном распределении память. Другими словами, Нет'т указатели на отдельные элементы. Для некоторых, довольно крайних случаях, это может стать существенно неэффективным. В типичных случаях, однако, [это рекомендуется для управления списками в C++][6].Примечание: из всех этих, только
raw_pointer_demo
на самом деле требует, что список будет явно уничтожен во избежание, что "утечка" Память. Три другие методы автоматически уничтожить список и его содержимое, когда контейнер выходит из области видимости (в конце функции). Суть вот в чем: С++ может быть очень "на Java-подобном" в этом отношении, - но только если вы решите разработать свою программу, используя высокоуровневые инструменты в вашем распоряжении.Обзор
Существует 2 способа ведения и выделять объекты в C++, а на Java есть только один способ.
Для того, чтобы объяснить следующие схемы показывают, как объекты хранятся в памяти.
1.1 с++ без указателей
Предупреждение: синтаксис языка C++, используемый в этом примере, аналогичен синтаксису на Java. Но, выделение памяти другая.
1.2 В C++ элементы, используя указатели
Если вы увидеть разницу между обе стороны, вы'увидите, что в первой методике, пункт-адрес выделяется в рамках поддержки, в то время как второй способ, вы должны создать каждый адрес явным образом.
Предупреждение: в Java выделяет объекты в памяти, как это второй способ., но синтаксис, как и первый способ, который может ввести в заблуждение новичков, чтобы "в++" и
Реализации
Так что пример ваш список может быть что-то похожее на следующем примере.
На стороне записки, если первый член класса или структуры следующим указателем (так что никаких виртуальных функций или любой другой функции класса, который будет означать рядом это't первый член класса или структуры), то вы можете использовать и"база" Класс или структура с рядом указатель, и использовать общий код для основных связанного списка операций, как добавление, вставка и прежде, получать от фронта, ... . Это потому, что C / С++ гарантирует, что адрес первого члена класса или структуры так же, как Адреса класса или структуры. Базовый узел Class или struct будет иметь только указатель Next, которые будут использоваться базовые функции связанного списка, затем типажей будут использоваться по мере необходимости, чтобы конвертировать между базовым типом узла и "производные" и типы узлов. Примечание - в C++, если базовый класс узел имеет только указатель Next, то я предполагаю, что производные классы могут'т иметь виртуальные функции.
Причина в том, что при создании "узел" объекта, компилятор должен выделить память для этого объекта и размер объекта рассчитывается. Размер указателя на любой тип известен компилятору и поэтому с самоопределяемый размер указателя объекта может быть рассчитана.
Если узел m_node
используется, то компилятор не имеет понятия о размерах "узел" и она застряла в *бесконечная рекурсия* расчета
оператор sizeof(узел)`. Всегда помните: класс не может содержать членов своего типа.Потому что это на Си++
эквивалентно этому в Ява
где оба они создают новый объект
класса MyClass
, используя конструктор по умолчанию.