Скрытие имени в списке инициализации конструктора

Я хочу изменить конструктор, чтобы использовать список инициализации, как в следующем примере:

class Foo
{
public:
   Foo(std::wstring bar);
private:
   std::wstring bar;
};

// VERSION 1:

Foo::Foo(std::wstring bar) {this->bar = bar}

// VERSION 2:

Foo::Foo(std::wstring bar) : this->bar(bar) {} // ERROR!

К сожалению, я не могу сделать версию 2, потому что вы не можете использовать указатель this для элементов данных, поскольку (я предполагаю), что они еще не существуют на тот момент. Как же мне решить проблему сокрытия имени (т. е. мой параметр и мой член данных имеют одно и то же имя)?


person JBentley    schedule 05.02.2013    source источник


Ответы (4)


Вам не нужно. Первый bar будет ссылаться на элемент, а второй bar будет ссылаться на аргумент:

Foo::Foo(std::wstring bar) : bar(bar) {}
person Joseph Mansfield    schedule 05.02.2013

Я бы изменил название аргумента, чтобы было понятно, что есть что.

Foo::Foo(std::wstring b) : bar(b) {}

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

Альтернативный вариант:

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

class Foo
{
public:
   Foo(std::wstring bar);
private:
   std::wstring bar_;
};

Foo::Foo(std::wstring bar) : bar_(bar) {}
person Michael Kristofik    schedule 05.02.2013

Вы действительно можете сделать это:

Foo::Foo(std::wstring bar) : bar(bar) {}

Все инициализаторы, используемые после :, должны ссылаться либо на базовый класс, либо на какой-либо член. Это означает, что ваш bar участник не будет скрыт в этот момент.

person mfontanini    schedule 05.02.2013

Компилятор будет знать, что делать... просто удалите это->

person Kane Anderson    schedule 05.02.2013