Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about assigning default constructor to *this in C++?

I am reading some C++ text. In an example, the text written:

class Student {
     int no;
     char grade[M+1];
 public:
     Student();
     Student(int, const char*);
     const Student& set(int, const char*);
     void display() const;
 };

Student::Student() {
    no = 0;
    grade[0] = '\0';
 }

 Student::Student(int n, const char* g) { 
     *this = Student(); // initialize to empty
     set(n, g);         // validate, reset if ok
 }

I don't understand this line: *this = Student();

Why do we have to do that, while just calling Student(); also makes the default constructor invoked? Thanks

like image 454
ipkiss Avatar asked Apr 26 '11 09:04

ipkiss


People also ask

What happens when default constructor is called?

In both Java and C#, a "default constructor" refers to a nullary constructor that is automatically generated by the compiler if no constructors have been defined for the class. The default constructor implicitly calls the superclass's nullary constructor, then executes an empty body.

Is default constructor always created?

No default constructor is created for a class that has any constant or reference type members. A constructor of a class A is trivial if all the following are true: It is implicitly declared. or explicitly defaulted.

Is default constructor called automatically?

Is a default constructor automatically provided? If no constructors are explicitly declared in the class, a default constructor is provided automatically by the compiler.

Can we provide one default constructor for our class?

No, the C++ compiler doesn't create a default constructor when we initialize our own, the compiler by default creates a default constructor for every class; But, if we define our own constructor, the compiler doesn't create the default constructor.


2 Answers

It's not possible to call the default constructor directly (C++ FAQ). ie.

Student::Student(int n, const char* g){
Student();
set(n, g); // validate, reset if ok
}

doesn't work. However I'm not sure about the solution you have, either.

*this = Student()

will call Student::operator=(const Student&). In this particular class it's OK (that function is the default member copy) but it might not be in general, because the Student object is only 'partly constructed' when that method is called.

Better to have a private init function

void Student::init() {
 no = 0;     
 grade[0] = '\0';
}

and call it from both constructors.

like image 144
Peter Hull Avatar answered Nov 14 '22 23:11

Peter Hull


Although, imho, it would be better to use common initialization function, something like this:

class Student {
    (...)
    private:
        void initMe();
 };

 Student::Student() {
    initMe();
 }

 Student::Student(int n, const char* g) { 
     initMe(); // initialize to empty
     set(n, g);         // validate, reset if ok
 }


void Student::initMe() {
    no = 0;
    grade[0] = '\0';
 }

That would avoid unnecessary creation of objects.

like image 30
baderman Avatar answered Nov 14 '22 23:11

baderman