Вопрос о назначении конструктора по умолчанию для * this в C ++? - PullRequest
5 голосов
/ 26 апреля 2011

Я читаю текст на C ++. В примере текст написан:

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
 }

Я не понимаю эту строку: *this = Student();

Почему мы должны это делать, хотя простой вызов Student(); также вызывает конструктор по умолчанию? Спасибо

Ответы [ 4 ]

7 голосов
/ 26 апреля 2011

Невозможно вызвать конструктор по умолчанию напрямую ( C ++ FAQ ).то есть.

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

не работает.Однако я не уверен насчет вашего решения.

*this = Student()

позвонит Student::operator=(const Student&).В этом конкретном классе все в порядке (эта функция является копией члена по умолчанию), но в целом это может быть не так, потому что объект Student создается только «частично» при вызове этого метода.

Лучше иметь приватныйФункция инициализации

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

и вызов ее из обоих конструкторов.

3 голосов
/ 26 апреля 2011

Хотя, imho, было бы лучше использовать общую функцию инициализации, что-то вроде этого:

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';
 }

Это позволит избежать ненужного создания объектов.

1 голос
/ 26 апреля 2011

*this = Student(); просто для инициализации переменных-членов по отношению к вызываемому конструктору по умолчанию.Такого дизайна следует избегать, так как он создает временное содержимое и копирует его содержимое.

Используйте что-то вроде ниже:

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
 }
1 голос
/ 26 апреля 2011

Создает временный объект Student, а затем копирует его в *this. Я бы просто инициализировал переменные-члены для очистки во втором конструкторе. Идея состоит в том, что вам не нужно писать один и тот же код, который дважды инициализирует переменные-члены как пустые, но здесь это довольно тривиальная проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...