C ++ - Есть ли различия между использованием `this` для инициализации члена на уровне класса и` this` в конструкторе? - PullRequest
0 голосов
/ 28 февраля 2019

К моему удивлению, я узнал, что код, подобный этому, на самом деле работает:

class A {
    B b;
    C c = this->b.GetC();
}

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

Тем не менее, это плохой стиль?Каковы различия между кодом выше и простой инициализацией C в конструкторе для A?

class A {
    B b;
    C c;

    A() {
        c = this->b.GetC();
    }
}

(или просто A() : c(this->b.GetC()) {}).

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Однако, для меня также имеет смысл, что на уровне класса мы объявляем шаблон, для которого должен копироваться каждый экземпляр класса, а на уровне "объявления" this не должно существоватьеще.Но C ++ никогда не перестает удивлять, и приведенный выше код, похоже, работает.

Вы правы.Если бы у вас было

struct foo
{
    int bar;
    decltype(this->bar) baz;
};

, вы бы получили ошибку компилятора при использовании this на верхнем уровне класса.

В вашем случае при использовании this, как

C c = this->b.GetC();
//or
C c{this->b.GetC()};

на самом деле не использует this на верхнем уровне.Инициализатор члена класса in является просто синтаксическим сахаром для сообщения классу, что, если вы не инициализируете член вручную, вы должны использовать предоставленный инициализатор.Таким образом, вы на самом деле не используете this в теле класса, вы просто используете ярлык.

Каковы различия между кодом выше и простой инициализацией Cв конструкторе для A?

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


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

0 голосов
/ 28 февраля 2019

В чем именно заключаются различия между кодом выше и простой инициализацией C в конструкторе для A?

Это полностью эквивалентно A() : c(b.GetC()) {}.Разницы нет.

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

уровень «объявления», которого еще не должно быть.Но C ++ никогда не перестает удивлять, и приведенный выше код, кажется, работает.

Так что это может существовать на уровне классов в C ++?

Нет.Инициализатор запускается при вызове конструктора.Элемент для инициализации существует только при создании экземпляра.

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