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, co开发者_JAVA技巧nst 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
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.
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.
It constructs a temporary Student
object, and then copies it to *this
. I would just initialize the member variables to empty in the second constructor though. The idea is that you don't have to write the same code that initializes the member variables as empty twice though, but it is quite trivial problem here.
*this = Student();
is just to initialize the member variables with respect to default constructor called. Such design should be avoided, as it creates temporary and copies it contents.
Use something like below:
void reset() { // introduce this method inlined in the class
grade[no = 0] = '\0';
}
Student::Student() {
reset(); // call it when needed
}
Student::Student(int n, const char* g) {
reset(); // initialize to empty
set(n, g); // validate, reset if ok
}
精彩评论