3

我是 C++ 新手,我正在尝试使用如下所示的 LinkedListIterator 实用程序类编写 LinkedList 类。(我只列出了与问题相关的代码部分)。我已将 LinkedListIterator 构造函数创建为私有的。

现在,当我在 main() 中有这两行时,

    LinkedListIterator iter = list->begin(); <<== No compilation error 
    LinkedListIterator iter2;  <<==== compilation error.         

我得到了第二行的编译错误,这是预期的,因为默认构造函数是私有的。但是,我不明白为什么第一行没有编译错误?为什么 ?代码的第一行调用了什么?私有构造函数或复制构造函数或赋值运算符?

代码

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.         

}
4

2 回答 2

8

LinkedListIterator iter = <some other LinkedListIterator>被称为复制初始化并调用“隐藏”构造函数:复制构造函数(C ++ 03)resp。移动构造函数(如果存在,并且如果初始值设定项是临时的,在 C++11 中)。您的代码中没有提供这两个构造函数,但它们存在:它们由编译器生成,并且它们是作为公共生成的。因此,它们可以从类外部访问,并且不会出现编译器错误。

Bartek 在他的回答中提到了复制省略,所以为了清楚起见,我将添加我的评论:复制/移动 ctor 必须可访问(在这种情况下:公共)以进行复制初始化,无论是否发生复制省略,即即使它不会被调用。

于 2014-05-27T14:11:46.633 回答
3

没有编译错误,因为构造函数是从(即“对象是在其中创建的”)LinkedList类(特别是从其begin()成员函数)调用的,这是一个friend. 没有其他人可以实例化该类,因此第二行失败。


具体来说,看begin()

inline LinkedListIterator LinkedList::begin()
{
    return first_;
}

它(关于访问)相当于:

    return LinkedListIterator(first_);

调用private LinkedListIterator::LinkedListIterator(Node* p).

然后,可以执行复制省略或者可以调用默认为公共的默认复制(或移动)构造函数。

于 2014-05-27T14:00:34.107 回答