slinkedlist *s1 = NULL;
определяет указатель на slinkedlist
и выполняет его инициализацию. К сожалению, он инициализирует его значением NULL, адресом безопасной парковки, где (как правило) ни один объект не может существовать. Для подавляющего большинства процессоров (каждый процессор, на котором я когда-либо работал) доступ к этой мертвой зоне вокруг NULL приведет к взлому sh программы, что значительно упростит обнаружение ошибок.
Нет необходимости указатель здесь. Если вам не нужен указатель, не используйте его. Ваша жизнь будет намного проще.
int main()
{
slinkedlist s1; // default initializes
s1.insertNode(4, -1);
s1.displayList();
while(1); // rethink this. If you want to hold a program open to see the output
// while debugging, place a breakpoint in the debugger.
}
Инициализация по умолчанию из s1
сама по себе не поможет, поскольку она выполнит абсолютную минимальную работу по инициализации своих переменных-членов, а также в В случае указателя минимальная работа - ничего не делать и оставлять head
и tail
неинициализированными и указывать (вроде. tail
НЕ указатель) на неопределенное место. Поскольку вы также не спрашиваете об ошибке компилятора, которую вы должны получить, присваивая NULL
для tail
, программа явно не инициализирует tail
, и я предполагаю, что конструктор slinkedlist
мало что делает.
Примечание: если у вас есть конструктор или деструктор, который ничего не делает (и не должен ничего делать), оставьте их и позвольте компилятору сгенерировать соответствующий код. Код, который не существует (и не должен существовать), не содержит ошибок.
class slinkedlist
{
public:
//ctor, dtor, insertNode(int, int), displayList()
private:
node* head, tail; // the * only applies to head.
};
может быть
class slinkedlist
{
public:
//ctor, dtor, insertNode(int, int), displayList()
private:
node* head = nullptr;
node* tail = nullptr;
};
, если вы компилируете в последний (2011 или более новый) C ++ Стандарты. Вам не понадобится конструктор, работа сделана за вас с заданиями по умолчанию. Вам все еще понадобится деструктор вместе с конструктором копирования и оператором присваивания, чтобы удовлетворить Правило трех .
В старых стандартах C ++ вам нужно сделать конструктор умнее
class slinkedlist
{
public:
slinkedlist(): head(NULL), tail(NULL)
{
}
//dtor, insertNode(int, int), displayList()
private:
node* head; // I recommend splitting the definitions up. It makes the code easier
// to read and makes it harder to make mistakes.
node* tail;
};
Вам все еще понадобятся деструктор, конструктор копирования и оператор присваивания.
Обратите внимание, что это также относится к node
. Если вы динамически выделяете узел и не устанавливаете в явном виде значение next
, вы не будете знать, куда указывает next
, и все тесты, такие как
while(head->next != NULL)
, будут ужасно провалены.