Конструктор базовых классов C ++ - PullRequest
0 голосов
/ 26 августа 2018

Я сейчас прохожу курс C ++, и они хорошо объясняют все до тех пор, пока не дойдет до разделения файлов между «обещаниями» заголовка и реализацией.Я полностью изучил программирование на Python, поэтому я привык просто объявлять вещи и импортировать класс по мере необходимости, так что весь этот процесс, состоящий в разделении обещания и последующей реализации логики, для меня странен.

В любом случае, у меняпроблема в том, что в ходе курса они говорили, что на самом деле вам никогда не нужно использовать this->, но когда я пытаюсь явно определить класс в том же файле .cpp, я могу заставить конструктор работать только тогда, когда я использую this->.Может кто-нибудь объяснить или связать обсуждение, которое объясняет это?Мне не удалось найти ссылку, которая объясняет эту проблему в контексте определения всего в одном файле.

class Person {
    public:
    string name;
    int age;
    int height;
    int weight;
    Person (string name, int age, int height, int weight) {
        name = name;
        age = age;
        height = height;
        weight = weight;
    }   
};

int main () {
    Person new_person("Doug", 20, 70, 170);
}

Это приводит к тому, что все значения, которые я передаю из основной функции, не инициализируются.Однако, если я добавлю this-> к каждой строке в конструкторе, все будет работать нормально.Примеры, которые я нашел, не используют this->, поэтому я запутался, почему это необходимо здесь.Возможно, это связано с пространствами имен, которые все еще немного сбивают меня с толку (в целом используется пространство имен std; вещь), но я подумал, поскольку это все в одном файле .cpp, это должно работать.

Ответы [ 4 ]

0 голосов
/ 26 августа 2018

Единственная проблема с подходом ->this состоит в том, что это А) многословно б) не инициализирует объект.c) делает этот объект нетривиальным.

Правильный конструктор инициализации выглядел бы так, используя список инициализации:

Person (string nm, int ag, int ht, int wt): 
    name(nm), age(ag), height(ht), weight(wt) {}

На самом деле это не то же самое, что делать то, что вы делаете, в этом случае объектможет быть создан статически без каких-либо действий.Ваша реализация класса всегда выполняет задания.C ++ 11 и более поздние версии позволяют покончить с тривиальной реализацией:

class Person {
    public:
    string name;
    int age;
    int height;
    int weight;

    void do_stuff() {};
};

// let's assume that string is std::string, 
// creation from  const char* and = are defined
int main()
{
  Person p = { "Nemo", 35, 5, 120 };
  Person p2 = p;
  p = { "John-117", 24, 6, 170 };
}
0 голосов
/ 26 августа 2018

Переменные аргумента затмевают ваши переменные-члены в области видимости вашего конструктора.То есть в этом контексте name относится только к входной переменной.

Что вы можете сделать, это использовать список инициализации:

Person (string name, int age, int height, int weight) :
    name(name), age(age), height(height), weight(weight) {}

Или использовать другие имена:

Person (string _name, int _age, int _height, int _weight) {
    name = _name;
    age = _age;
    height = _height;
    weight = _weight;
}   

Но ваш подход с использованием this-> вполне подходит.

Возможно, вы также захотите прочитать http://www.cs.technion.ac.il/users/yechiel/c++-faq/using-this-in-ctors.html

0 голосов
/ 26 августа 2018

Имеется случай неоднозначности зависимых имен . Смотрите здесь :

Если поиск члена текущего экземпляра дает другой результат между точкой создания и точкой определения, поиск неоднозначен. Обратите внимание, что при использовании имени члена оно не преобразуется автоматически в выражение доступа члена класса, только явные выражения доступа к элементам указывают членов текущего конкретизация:

Эли Бендерский красноречиво пишет об этом . Выдержка:

Все, что вам нужно сделать, это заставить компилятор понять, что вызов f зависит от параметра шаблона T. Для этого есть несколько способов: заменить f () на Base :: f () или this-> f () (поскольку это неявно зависит от T).

Так что ваше собственное this-> решение более чем прекрасно:)

0 голосов
/ 26 августа 2018

В этом случае вам нужно this, потому что вы используете одно и то же имя для параметров конструктора и членов класса.

Person (string name, int age, int height, int weight) {
    this->name = // this-> means the member variable
        name;    // just the parameter

Если бы у вас было другое имя для вашего параметра this не было бы необходимости

Person (string name_, int age, int height, int weight) {
    name =      // the member variable
        name_;  // the parameter
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...