Роль спецификаторов доступа в typedefs и предварительном объявлении

Рассмотрим следующий пример кода для класса связанного типа списка. Я хочу объявить метод, который возвращает итератор, который является typedef для Node*, Тем не мение, Node является частным вложенным классом, поэтому для того, чтобы сделать typdef, я должен сообщить компилятору о Node с предварительной декларацией.

Наивно, я думал, что оба дефолта к частному сработают; что-то вроде этого:

class List
{
class Node;
typedef Node* Iterator;
public:
List() : head_(NULL), tail_(NULL) {}
Iterator begin() {return head_;}

private:
class Node
{
private:
int data_;
};

Node* head_;
Node* tail_;
};

int main()
{
List list;
List::Iterator = list.begin();
return 0;
}

что приводит к ошибке времени компиляции в строке 4:

‘typedef class List :: Node * List :: Iterator’ является приватным
компиляция прервана из-за ошибок -Wfatal.

Нетрудно понять, почему предварительная декларация class Node; принадлежит в личном разделе, но как насчет typedef Iterator Node*;? Это, вероятно, связано с моим непониманием typedef ключевое слово, но почему это важно, какой спецификатор доступа применяется? я думал private имеет больше смысла из-за видимости Node учебный класс.

Это как-то связано с typedefЯвляется ли частью публичного интерфейса? Все ли typedef должны быть объявлены с public видимость?


Редактировать:
Позвольте мне уточнить, я понимаю, что я могу остановить свой компилятор от жалоб, переместив typedef в public. Я не понимаю, почему это необходимо.

1

Решение

Вы можете просто сделать typedef name публичным именем. Попробуйте следующее

class List
{
public:
typedef class Node* Iterator;

Также учтите, что для обоих классов вы забыли поставить точки с запятой после закрывающих скобок. 🙂

1

Другие решения

List::Iterator является закрытым, поэтому имя не может быть использовано, но тип может быть выведен

List l;
List::Iterator it = l.begin(); // Illegal
auto it = l.begin(); // legal

или же

template <typename IT>
void foo(IT it);

foo(l.begin()); // legal

Кстати, вы можете иметь List::Iterator публично, и держать List::Node частный.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector