Частные переменные-члены С++ с тем же именем, что и параметры ctor

Я знаю, что многие люди используют префикс или суффикс для имен закрытых переменных-членов. Для тех, кто этого не делает, а просто использует имя - как вы их инициализируете, если хотите иметь параметры конструктора с тем же именем?


person SRobertJames    schedule 12.04.2015    source источник
comment
Вы можете постфиксировать _ к именам параметров.   -  person πάντα ῥεῖ    schedule 12.04.2015
comment
Члены с префиксом m_ или s_ (для статики)   -  person Ed Heal    schedule 12.04.2015
comment
Вы можете использовать this для устранения неоднозначности.   -  person tux3    schedule 12.04.2015


Ответы (5)


Просто написав их. Правила языка предотвращают проблемы.

struct Foo
{
   Foo(int x) : x(x) {};
   int x;
};

Вне () в область действия входит только член данных; внутри аргумент функции скрывает член так же, как в обычном теле функции:

int x = 2;
void foo(int x)
{
   // any access to `x` means the argument
}

Это одна из многих причин, по которым я не использую стиль префикса m_ (или аналогичный) при именовании элементов данных.

person Lightness Races in Orbit    schedule 12.04.2015

Вы просто инициализируете их в списке инициализации:

struct foo
{
  foo(int bar) : bar(bar) {}
 private:
  int bar;
};

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

Кроме того, C++ позволяет вам инициализировать член в точке объявления, и в этом случае он инициализируется этим значением, если иное не инициализировано в конструкторе:

struct foo
{
  foo(int bar) : bar(bar) {}
  foo() {} // bar initialized to 42
 private:
  int bar = 42;
};
person juanchopanza    schedule 12.04.2015

Если вы используете список инициализаторов, вы можете просто использовать то же имя, и компилятор поймет, что вы имеете в виду.

Пример:

Book::Book(std::string title, int year) 
: title(title), year(year)
{}
person newprogrammer    schedule 12.04.2015

Самый простой способ — использовать список meme-initializer. Например

class A
{
private:
   int data;
public:
   A( int data ) : data( data ) {}
};

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

class A
{
private:
   int data;
public:
   A( int data ) : data( data ) 
   {
        A::data    *= data;
        this->data *= data;
   }
};
person Vlad from Moscow    schedule 12.04.2015
comment
За исключением того, что теперь ваш член имеет в три раза больше необходимого значения. Не хорошая работа. - person Lightness Races in Orbit; 12.04.2015

Формальное имя метода не имеет большого значения, учитывая, насколько ограничена его область применения. И все же должна быть мотивация, чтобы иметь возможность мгновенно различать «происхождение» этих предметов с первого взгляда.

Это стало моей практикой для обоих

а) добавьте к именам атрибутов данных префикс «m_»,

И

б) ставить перед именами параметров метода/функции префикс 'a_' или 'an_', всегда стремясь к грамматической правильности.

LMBM::Node::Node(uint8_t a_max) : m_max (a_max) ...

void* LMBM::Node::threadEntry(void* an_objPtr) ...

void   DV1::processDirent(const std::string&  a_dirPath) ...

void   DV1::handleDT_REG (DV::Dirent*        an_ent,
                          const std::string& a_path) ...

FInfo (const std::string& aPfn, const int64_t& aFileSz) :
     m_pfn    (aPfn),
     m_fileSz (aFileSz) ...

Цель - легче читать

Мотивация - код пишется один раз, читается много раз

Я понимаю особый случай для списка инициализаторов ctor. Но я также уверен, что использование префиксов (по вашему выбору) помогает предотвратить несколько видов ошибок, возникающих во время разработки и обслуживания.

person 2785528    schedule 12.04.2015