3

私は C++ が初めてで、以下のように LinkedListIterator ユーティリティ クラスを使用して LinkedList クラスを作成しようとしています。(質問に関連するコード部分のみをリストしました)。LinkedListIterator コンストラクターをプライベートとして作成しました。

さて、main() にこれらの 2 行があると、

    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.         

}
4

2 に答える 2

8

LinkedListIterator iter = <some other LinkedListIterator>これはコピー初期化と呼ばれ、「隠し」コンストラクター (コピー コンストラクター (C++03) resp.) を呼び出します。コンストラクターを移動します (存在する場合、および初期化子が C++11 の一時的なものである場合)。これら 2 つのコンストラクターは、コードでは提供されませんが、存在します。これらはコンパイラーによって生成され、パブリックとして生成されます。したがって、それらはクラスの外部からアクセスでき、コンパイラ エラーは発生しません。

Bartek は彼の回答でコピーの省略について言及しているので、わかりやすくするために私の発言を追加します。呼び出されません。

于 2014-05-27T14:11:46.633 に答える
3

LinkedListコンストラクターがクラス (特にそのbegin()メンバー関数から) から呼び出される (つまり、「オブジェクトが作成される」) ため、コンパイル エラーは発生しませんfriend。誰もそのクラスをインスタンス化できないため、2 行目は失敗します。


具体的には、次を見てbegin()ください。

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

それは(アクセスに関して)以下と同等です:

    return LinkedListIterator(first_);

を呼び出しますprivate LinkedListIterator::LinkedListIterator(Node* p)

次に、コピー省略実行するか、デフォルトで public であるデフォルトのコピー (または移動) コンストラクターを呼び出すことができます。

于 2014-05-27T14:00:34.107 に答える