private constructor in C++

1.2k Views Asked by At

I am new to C++ and i am trying to write a LinkedList class with a LinkedListIterator utility class as below. (i have listed only the code parts that are relevant to the question). I have created the LinkedListIterator constructor as private.

Now, when I have these two lines in main(),

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

i get the compilation error for the 2nd line, which is expected as the default constructor is private. However, I dont understand why there is no compilation error for the first line ? Why ? what is getting called for the first line of the code ? Private constructor or Copy constructor or assignment operator ?

Code

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.         

}
2

There are 2 best solutions below

2
On BEST ANSWER

LinkedListIterator iter = <some other LinkedListIterator> is called copy initialization and calls a "hidden" constructor: the copy constructor (C++03) resp. move constructor (if present, and if the initializer is a temporary, in C++11). These two constructors are not provided in your code, yet they exist: They are generated by the compiler, and they are generated as public. Therefore they are accessible from outside the class and you do not get a compiler error.

Bartek mentions copy elision in his answer, so I'll add my remark for clarity: The copy/move ctor must be accessible (in this case: public) for copy initialization, regardless of wether copy elision takes place or not, i.e. even if it does not get called.

2
On

There's no compilation error because the constructor is called from (i.e. "the object is created in") the LinkedList class (in particular from its begin() member function), which is a friend. No one else can instantiate that class, so the second line fails.


Specifically, looking at begin():

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

it's (with regard to access) equivalent to:

    return LinkedListIterator(first_);

which calls private LinkedListIterator::LinkedListIterator(Node* p).

Then, copy ellision could be performed, or a default copy (or move) constructor, which is public by default, could be called.