Почему я не могу использовать оператор стрелки в списке инициализации?

Я новичок в С++. Недавно, когда я практиковался в написании связанного списка, я попытался использовать список инициализации для моего конструктора класса, чтобы назначить NULL в head-> next.

В конструкторе класса он предупредил, что мой оператор стрелки «ожидал '(' или '{'». Почему возникает такая ошибка? (Я знаю, что могу инициализировать члены класса прямо в блоке, но почему я не могу это с этим указателем?) Спасибо!

Вот мой заголовочный файл для связанного списка:

связанный список.h

#include <iostream>
using namespace std;

struct node {
int val;
node *next;
};

class linkedlist {
private:
node *head;
int listlen;

public:
linkedlist();
void insert(node*, int);
void del(node*);
void reverse(node*);
void traverse(node*);
int random();
~linkedlist();

};

И вот мой конструктор класса:

связанный список.cpp

#include "linkedlist.h"
#include <iostream>

linkedlist::linkedlist() :listlen(0), head->next(NULL){}

person Chongliang He    schedule 26.01.2017    source источник
comment
Две проблемы: во-первых, head не инициализирован. Во-вторых, у вас не может быть выражений в списке инициализаторов.   -  person Some programmer dude    schedule 26.01.2017
comment
@Someprogrammerdude как насчет постоянных выражений?   -  person Joel Cornett    schedule 26.01.2017
comment
Почему? Потому что так был разработан язык. (Предположительно, списки инициализации всегда предназначались для инициализации самого объекта, а не других объектов, на которые могут указывать его члены.)   -  person TheUndeadFish    schedule 26.01.2017
comment
@JoelCornett Можно использовать непостоянное выражение в качестве инициализатора в качестве значения, используемого для инициализации переменной-члена. Но не допускается иметь общее выражение для инициализируемой переменной (например, head->next).   -  person Some programmer dude    schedule 26.01.2017
comment
@Someprogrammerdude О, вы знаете, я совершенно неправильно понял конструктор. Я понял.   -  person Joel Cornett    schedule 26.01.2017
comment
@ Какой-то программист, чувак, я немного запутался с этим указателем головы. Должен ли я инициализировать head или head-›next или оба? Почему?   -  person Chongliang He    schedule 26.01.2017


Ответы (1)


Как правило, вы можете инициализировать только сами элементы как часть списков инициализации. Если бы это была ваша единственная проблема, то вы могли бы просто инициализировать следующий указатель на NULL как часть тела ctor. Однако ваша переменная-член head сама по себе является указателем и в настоящее время никуда не указывает, поэтому я подозреваю, что вы действительно хотели установить head в NULL (или nullptr, если вы используете С++ 11 или более позднюю версию):

linkedlist::linkedlist() :listlen(0), head(NULL) {}

Вы также можете дополнительно добавить ctor к вашему struct node для инициализации next до NULL при инициализации.

Несколько других вещей, которые, по моему мнению, стоило бы указать, поскольку вы сказали, что вы новичок:

  1. Обратите внимание, что списки инициализации запускаются не в том порядке, в котором они написаны в ctor, а в том порядке, в котором члены определены в теле класса. В вашем случае здесь этот listlen фактически инициализируется 0 только после инициализации head. Это не имеет значения для вашего кода здесь, но может иметь значение, если инициализация элементов более сложна и имеет зависимости. Лично я бы рекомендовал всегда поддерживать порядок списков инициализации в соответствии с порядком определений элементов. Некоторые компиляторы также имеют флаги для предупреждения, если это не так.

  2. Рассматривали ли вы возможность использования структуры данных из стандартной библиотеки вместо реализации собственного связанного списка? Посетите сайт cppreference.com, чтобы найти много полезной информации об этом. В частности, проверьте «список», «вектор» или «дек» в зависимости от вашего варианта использования.

person TKL    schedule 26.01.2017
comment
Спасибо за ваш вклад! Я буду иметь в виду порядок инициализации. И, что касается самой структуры данных, необходимы ли инициализация указателя head как NULL и head-›next как NULL? - person Chongliang He; 26.01.2017
comment
Если вы этого не сделаете, они будут иметь неопределенное значение, что для указателей означает, что они недействительны и, вероятно, вызовут SEGV, если вы попытаетесь разыменовать их. По этой причине в большинстве случаев вы захотите инициализировать их явно, чтобы позже вы могли рассуждать о значениях. Я говорю в большинстве случаев, потому что иногда у вас может быть другое состояние, которое позволяет вам гарантировать, что вы не получите доступ к этим членам, пока они не будут инициализированы. - person TKL; 26.01.2017