Я новичок в C ++, и я пытаюсь написать класс LinkedList с помощью служебного класса LinkedListIterator, как показано ниже. (Я перечислил только те части кода, которые имеют отношение к вопросу). Я создал конструктор LinkedListIterator как частный.
Теперь, когда у меня есть эти две строки в main (),
LinkedListIterator iter = list->begin(); <<== No compilation error
LinkedListIterator iter2; <<==== compilation error.
я получаю ошибку компиляции для 2-й строки, которая ожидается, поскольку конструктор по умолчанию является закрытым. Тем не менее, я не понимаю, почему нет ошибки компиляции для первой строки? Зачем ? что вызывается для первой строки кода? Частный конструктор или Копировать конструктор или оператор присваивания?
class LinkedListIterator {
public:
bool operator== (LinkedListIterator i) const;
bool operator!= (LinkedListIterator i) const;
void operator++ (); // Go to the next element
int& operator* (); // Access the current element
inline Node* hasnext();
inline Node* next();
private:
LinkedListIterator(Node* p); <<==== Private constructor
LinkedListIterator(); <<==== Private constructor
Node* p_;
friend class LinkedList;//LinkedList can construct a LinkedListIterator
};
....
inline LinkedListIterator::LinkedListIterator(Node* p)
: p_(p)
{ }
inline LinkedListIterator::LinkedListIterator()
{ }
inline LinkedListIterator LinkedList::begin()
{
return first_;
}
inline LinkedListIterator LinkedList::end()
{
return NULL;
}
.......
class LinkedList {
public:
void append(int elem); // Adds elem after the end
void printList();
LinkedList() {
first_ = NULL;
}
LinkedListIterator begin();
LinkedListIterator end();
LinkedListIterator erase(int elem);
private:
Node* first_;
};
main()
{
LinkedList *list = new LinkedList();
list->append(1);
list->append(2);
list->append(3);
LinkedListIterator iter = list->begin(); <<== No compilation error
LinkedListIterator iter2; <<==== compilation error.
}
LinkedListIterator iter = <some other LinkedListIterator>
называется инициализация копии и вызывает «скрытый» конструктор: конструктор копирования (C ++ 03) соотв. Переместить конструктор (если он есть, и если инициализатор временный, в C ++ 11). Эти два конструктора не предусмотрены в вашем коде, но они существуют: они генерируются компилятором, и они генерируются как общедоступные. Поэтому они доступны извне класса, и вы не получите ошибку компилятора.
Бартек упоминает об исключении копии в своем ответе, поэтому я добавлю мое замечание для ясности: ctor копии / перемещения должен быть доступен (в данном случае: public) для инициализации копии, независимо от того, имеет ли место удаление копии, т.е. даже если это не называют.
Там нет ошибки компиляции, потому что конструктор вызывается из (т. Е. «Объект создан в») LinkedList
класс (в частности, из его begin()
функция-член), которая является friend
, Никто другой не может создать экземпляр этого класса, поэтому вторая строка завершается ошибкой.
В частности, глядя на begin()
:
inline LinkedListIterator LinkedList::begin()
{
return first_;
}
это (в отношении доступа) эквивалентно:
return LinkedListIterator(first_);
какие звонки private
LinkedListIterator::LinkedListIterator(Node* p)
,
Затем скопируйте Ellision мог быть выполненным, или конструктор копирования (или перемещения) по умолчанию, который является общедоступным по умолчанию, может быть вызван.