Функция-член не может ссылаться на переменные-члены * stati c - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь написать код для решения проблемы Иосифа, для упражнения в книге, которую я сейчас читаю.

main. cc:

#include <iostream>
#include <cstdlib>
#include "node_ll.h"

int main(int argc, char *argv[])
  { int i, N = atoi(argv[1]), M = atoi(argv[2]);
    Node<int> *t, *x;
    Node<int>::construct(N);
    for (i = 2, x = Node<int>::newNode(1); i <= N; i++)
      {
        t = Node<int>::newNode(i);
        x->insert(t);
        x = t;
      }
    while (x != x->next())
      {
        for (i = 1; i < M; i++) x = x->next();
          x->remove()->deleteNode();
      }
    std::cout << x->item() << std::endl;
    return 0;
  }

node_ll .h:

#ifndef NODE
#define NODE

template <class T>
class Node
{
private:
  static Node* freelist;
  Node* link;
  T data;

public:
  static Node* newNode(T);
  static void construct(int);
  void deleteNode();
  void insert(Node*);
  Node* remove();
  Node* next();
  T item();
};

template <class T>
void Node<T>::insert(Node* t)
{
  t->link = link;
  link = t;
}

template <class T>
Node<T>* Node<T>::remove()
{
  Node* t{link};
  link = t->link;
  return t;
}

template <class T>
Node<T>* Node<T>::next()
{
  return link;
}

template <class T>
T Node<T>::item()
{
  return data;
}

template <class T>
Node<T>* Node<T>::newNode(T x)
{
  Node* t{freelist->remove()};
  t->data = x;
  t->link = t;
  return t;
}

template <class T>
void Node<T>::construct(int N)
{
  freelist = new Node[N+1];
  for(int i{0}; i < N; i++)
    freelist[i].link = &freelist[i+1];
  freelist[N].link = 0;
}

template <class T>
void Node<T>::deleteNode()
{
  freelist->insert(this);
}
#endif

При компиляции g ++ выдает следующую ошибку:

/ usr / bin / ld: /tmp/ccNqFpW8.o: в функции Node<int>::construct(int)': main.cc:(.text._ZN4NodeIiE9constructEi[_ZN4NodeIiE9constructEi]+0x31): undefined reference to Node :: freelist ' / usr / bin / ld: main. cc :(. text._ZN4NodeIiE9constructEi [_ZN4NodeIiE9constructEi] + 0x4e): неопределенная ссылка на Node<int>::freelist' /usr/bin/ld: main.cc:(.text._ZN4NodeIiE9constructEi[_ZN4NodeIiE9constructEi]+0x65): undefined reference to Узел :: freelist '/ usr / bin / ld: main. cc :( .text._ZN4NodeIiE9constructEi [_ZN4NodeIiE9constructEi] + 0x85): неопределенная ссылка на Node<int>::freelist' /usr/bin/ld: /tmp/ccNqFpW8.o: in function Node :: newNode (int) ': main. cc :(. text._ZN4NodeIiE7newNodeEi [_ZN4Nodei * 1011: 0E) Node :: freelist 'follow collect2: error: ld вернул 1 состояние выхода

И я понятия не имею, что происходит

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Я исправил это, объявив freelist как:

inline static Node* freelist;

вместо:

static Node* freelist;

и скомпилировав его для c ++ 17

, найденного здесь: Как инициализировать приватные члены c в C ++?

0 голосов
/ 26 апреля 2020

Вы объявляете члена класса статичным c. Это означает, что для каждого экземпляра создаваемого вами класса все они будут ссылаться на одно и то же значение stati c. Поскольку существует только одно значение, его нужно инициализировать один раз где-нибудь в вашей программе. Так что вам не хватает такого выражения, как:

Node<int>::Node* freelist = foo;    // The one-and-only 'foo' for all Node<int>s

Позвольте мне отметить, что для меня не имеет смысла, что все классы совместно используют один экземпляр этой переменной. Кроме того, ваш код также содержит этот конструктор:

template <class T>
void Node<T>::construct(int N)
{
  freelist = new Node[N+1];

Эта переменная не обрабатывается так, как если бы она была c, если вы также пытаетесь выполнить инициализацию для каждого экземпляра.

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