Constructor Initializers

I'm currently reading "Accelerated C++" and I have just read the chapter on defining types. I basically understood what constructors are used for and why they are important, I did not, however, fully understand how constructors are supposed to be implemented in a class declaration.

There are two types of constructors, default constructors and constructors that include arguments. Now the authors wrote that you should always define both types of constructors, e.g. like this:

1
2
3
4
5
6
class Student_info { 
public:
Student_info() 
Student_info(std::istream&); 
// as before
};


First of all, is there a reason why you do not have to put a semicolon behind a statement that defines a default constructor?

Then they go on to give a more specific example of a default constructor, where the two elements of the class that are of build-in type are to be given the value 0:

Student_info::Student_info(): midterm(O), final(0) { }

and then an example for a constructor with an argument:

Student_info::Student_info(istream& is) { read(is); }


Now a couple of questions:

My compiler(XCode) does not accept this kind of statement:
Student_info::Student_info(istream& is) { read(is); }
instead it only accepts the constructor definition in this way:
Student_info(istream& is) { read(is); }

I get the error: Expected member name or ";" after decleration specifiers. Why is that?

And most importantly I do not understand why you should define two kinds of constructors. Why would you default initialise a class object first and then later initialise it by reading input from the standard input into it?
Hi there,

A constructor which does not take any arguments is referred to as the default constructor. The compiler will provide you with one if you do not define it and do not define any other constructors (taking arguments). So as soon as you implement a non-default constructor, you have to implement the default one yourself. The default constructor declaration should also be ended with a semicolon. just like any other statement.

Now, there is an important difference between declaring a class and defining its member functions. In fact, declaration and definition are often split up into separate files. Not to confuse you, let's keep them in the same file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//class declaration, telling the compiler "I'll be using class Student_info and it looks like this"
class Student_info 
{ 
    public:
        //explicitly default the default constructor
        //viz. accept the compilers default constructor
        Student_info() = default; 
        Student_info(std::istream&); 
};


//class definition, telling the compiler "remember that class Student_info? this is how it works"

Student_info::Student_info(std::istream& is)
{
    read(is);
}


Now, let me furth explain this line: Student_info::Student::info(std::istream& is).
operator::() is known as the scope resolution operator, it allows you to tell the compiler where to look for a name. In this case, the constructor for Student_info is within the Student_info class, so we determine the class: Student_info:: then the constructor Student_info(std::istream& is).


Hope that helps, please do let us know if you have any further questions.

All the best,
NwN
Ok thanks a ton, I understand the second part now. It wasnt clear to me from the book that you would have to first declare a constructor in the header and then also define it in another file.

But I still dont get this part:

The compiler will provide you with one if you do not define it and do not define any other constructors (taking arguments). So as soon as you implement a non-default constructor, you have to implement the default one yourself.


Why do you have to implement a default constructor after you have implemented a non-default constructor? And what counts as defining a default constructor? Is this a definition of one?

Student_info() = default;

And I dont understand why you would have to start to implement the default constr. after you have implemented a non-default one. Why is the non-default constr. not sufficinet?
Hi there,

Well, technically you're not required to implement a default constructor if you implement another one. In fact, the parameterized constructor can be the default constructor for the class. This can be useful if you want to enforce certain behaviour to the user of your class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student_info 
{ 
    public:
        Student_info(std::istream&); 
};

Student_info::Student_info(std::istream& is)
{
    read(is);
}

int main()
{
    Student_info s1(std::cin); //works
    Student_info s2; //won't work
}


However, often people do expect a default no-argument constructor to be implemented. So what I should have said was that once you provide a constructor yourself, the compiler will not create a default constructor of its own.

Student_info() = default; Is the C++11 way of saying you accept the compilers default constructor, it's an easy way of implementing a no-argument constructor without having to provide a separate definition for it.

All the best,
NwN
Topic archived. No new replies allowed.