2013-09-06 5 views
0

Я пишу класс, где несколько экземпляров связаны друг с другом, как связанный список. Вот скелетный пример соответствующего кода:Const-correctness со связанным списком

class A 
{ 
    public: 
    void setNext(const A& node) { next = &node; } 
    const A& getNext() const { return *next; } 

    private: 
    const A* next; 
} 

Я объявил аргумент setNext как const, потому что node не изменяется setNext. Класс А также не изменяет следующий узел, поэтому переменная-член next объявлена ​​const. Проблема возникает с getNext. Независимо от того, какой объект получает следующий узел из текущего узла, очень может потребоваться изменить узел, но поскольку переменная-член const, возвращаемая ссылка должна быть также const.

Из того, что я читал, const_cast обычно указывает на плохой дизайн, но мне кажется, что мне нужно будет использовать его либо внутри объекта, который получает следующий узел, либо использует его в классе A для возврата неконстантной ссылки , Является ли это допустимым использованием const_cast или есть ли какой-то недостаток в моем проекте?

И пока мы по этому вопросу, есть ли предпочтение в той или иной форме, следует ли возвращать ссылку или указатель? У меня есть setNext возьмите ссылку, чтобы убедиться, что я получаю действительный экземпляр A, но возвращаемое значение может быть возвращено в любом случае.

+0

Я бы сказал, что так как А в 'getNext' предназначаются, чтобы позволить другим изменить возвращаемые object, то A облегчает модификацию своего «следующего» объекта, тогда член 'next' должен * not * быть' const'. То, как я это вижу, не имеет значения, изменит ли A '' next'' или позволяет другим это делать; в любом случае, что '* next' не остается постоянным, через этот конкретный указатель. – yzt

ответ

0

Я думаю, что связанный список частных пользователей должны быть неконстантная, потому что вы можете реализовать метод, который может пройти через список вызов определенной функции на каждого члена, например. Таким образом, ваш дизайн о следующем члене const может иметь множество ограничений. Другое дело, вы должны позаботиться о получении ссылки на свой setNext: как вы можете узнать конец своего списка? С помощью указателя вы можете установить следующий как NULL, и это будет конец списка. Но вы можете сохранить ваш член неконстантный и реализовать GetNext, которые возвращают константный объект, в этом случае вы будете иметь:

class A 
{ 
    public: 
    void setNext(A* node) { next = node; } 
    A& getNext() const { return *next; } 
    const A& getNext() const { return *next; } 

    private: 
    A* next; 
} 
+0

Это имеет смысл, я думал очень строго в том, что сам А не изменяет следующий, но поскольку он должен облегчить модификацию следующего, он действительно не должен быть 'const'. В этом случае список на самом деле является круговым списком, поэтому следующий никогда не должен быть NULL. Он инициализируется 'this' в конструкторе. –

0

Во-первых, не изобретайте велосипед. Если это возможно, используйте boost::intrusive, который уже внедрил такой навязчивый список, как это для вас, без дополнительной работы! Вы даже можете уйти с std::list или другим стандартным контейнером.

Но если есть к:

  • Указатель на следующую переменную не может быть const, потому что вы, возможно, потребуется изменить next узел он указывает.
  • setNext необходимо будет взять свой параметр с помощью ссылки, отличной от const, потому что вам нужно иметь возможность хранить указатель на неконтекстную позицию.
  • Создайте два перегруженных getNext: const A& getNext() const { return *next; } и A& getNext() { return *next; }
+0

Этот проект предназначен для микроконтроллера AVR, который не имеет стандартной библиотеки C++. Это мой первый набег на C++, поэтому я не знаком со всеми доступными библиотеками. Boost :: intrusive может работать, если ему не нужна стандартная библиотека C++, но в любом случае мне не нужна полная функциональность списка.Список будет фиксированным размером во время компиляции и просто станет более простым способом отслеживать объекты, чем массив указателей. –

Смежные вопросы