Что означают ведущие символы подчеркивания в конструкторе C ++?

Хорошо, я не очень опытный программист на C ++, но мне было интересно, каково значение подчеркиваний в аргументах следующего конструктора?

class floatCoords
 {
 public:
  floatCoords(float _x, float _y, float _width, float _height)
   : x(_x), y(_y), width(_width), height(_height)
  {

  }
  float x, y, width, height;
  ...

person Community    schedule 19.10.2009    source источник


Ответы (8)


Это просто удобное соглашение об именах, оно ничего не значит для языка. Только убедитесь, что вы не ставите после него заглавную букву: Что означает двойное подчеркивание (__const) в C?

person Mark Ransom    schedule 19.10.2009
comment
См. Также: stackoverflow.com/questions/228783/ - person Martin York; 20.10.2009

Ничего особенного. Он просто назвал его так, чтобы различать переменные-члены и имена параметров.

Подчеркивание - допустимый символ в идентификаторах C ++.

person mmx    schedule 19.10.2009
comment
Кроме того, обычно переменные-члены по соглашению имеют символы подчеркивания, а аргументы конструктора - нет. Однако все это действительно зависит от местного соглашения о кодировании. Некоторые магазины требуют m_ перед участниками. Однако избегайте двойного подчеркивания (зарезервировано для использования компилятором). см .: stackoverflow.com/questions/1228161/ - person jmhmccr; 20.10.2009
comment
Я видел достаточно кода, чтобы сказать, что ничто в именах закрытых членов, не говоря уже о подчеркивании, не является общепринятым. - person coppro; 20.10.2009
comment
Также обратите внимание, что это различие не является строго необходимым в ctor-initializer - поиск имени для членов находит только члены, а поиск имени внутри инициализатора сначала найдет имя параметра. - person coppro; 20.10.2009
comment
Как я уже сказал, местные соглашения: google-styleguide.googlecode.com/svn / trunk / Угадайте, что @coppro имелось в виду в общем. Какой правильный. - person jmhmccr; 20.10.2009

Скорее всего, автор кода пытался избежать потенциального конфликта между именами элементов данных и именами параметров конструктора в списке инициализаторов. Вполне вероятно, что автор не знал о том, что правила поиска C ++ гарантируют, что конфликт все равно не возникнет. Т.е. следующий код также даст ожидаемые результаты

class floatCoords    {
    public:
        floatCoords(float x, float y, float width, float height)
                : x(x), y(y), width(width), height(height)
        {
        }
        float x, y, width, height;
        ...

хотя это может сбить с толку неподготовленного читателя.

Конечно, внутри тела конструктора имена параметров будут скрывать имена членов, что делает необходимым использовать this->... или уточненные имена для доступа к элементам данных. Скорее всего, автор кода пытался этого избежать.

person AnT    schedule 19.10.2009
comment
Интересно, не знал этого лакомого кусочка. Однако, на мой взгляд, все же было бы лучше использовать имена параметров, которые не соответствуют именам переменных-членов. В этом случае вы можете использовать x и y в качестве параметров в ctor, но если бы вы писали методы setX и setY, вам пришлось бы использовать разные имена параметров. Я предпочитаю, чтобы имена моих параметров были единообразными во всем классе. - person ThisSuitIsBlackNot; 20.10.2009
comment
@ThisSuitIsBlackNot: Не обязательно. Синтаксис this->member позволяет реализовать ваши методы setX и setY, даже если имена параметров скрывают имена членов. Некоторые стандарты кодирования на самом деле требуют, чтобы к членам класса всегда обращались через синтаксис this->member (я должен признать, что в этом есть определенная ценность). - person AnT; 20.10.2009
comment
@AndreyT: Вы правильно подметили. При последовательном использовании синтаксис this- ›member очень ясен (я видел этот формат во многих классах Java). Однако что произойдет, если вы забудете эту часть? Я не уверен, что это за поведение, но полагаю, что это часто случается в крупных проектах. Даже если ничего страшного не произойдет, непоследовательность в коде меня бы смутила (тут я придираюсь). - person ThisSuitIsBlackNot; 20.10.2009

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

class A {
  void foo(int age_) { //parameter
    int age = 18; //local scope
    if (age_ > age) cout << legal << endl;
  }
  int _age; //member
};

В приведенном выше примере:

  • _variable - означает, что это переменная-член класса
  • variable_ - означает, что это параметр функции
  • переменная - означает, что это просто обычная переменная, локальная для области действия функции
person naumcho    schedule 19.10.2009
comment
и _Variable попадает в пространство имен разработчика. - person David Thornley; 20.10.2009

Это просто имена переданных параметров. Они совпадают с переменными-членами и используются для инициализаторов.

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

person Tim    schedule 19.10.2009

У них нет синтаксического значения. Однако, если у вас есть несколько полей (например, x, y, width и height), общепринято именовать параметры конструктора, которые инициализируют их, с именем поля плюс подчеркивание в начале.

person David Seiler    schedule 19.10.2009

Эти символы подчеркивания предназначены для различения переменной параметра float _x и переменной-члена float x. Синтаксически из-за подчеркивания особого значения не добавляется. Я лично предпочитаю ставить перед всеми параметрами префикс a_ и префикс всех переменных-членов с помощью m_, когда мне нужно кодировать C ++.

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

int y = a_x * 2;
m_x = y + 3;
person Eugene Yokota    schedule 19.10.2009

потому что, если вы назовете den float x, float y и т. д., вы не сможете получить доступ к фактическим полям класса, потому что они имеют то же имя.

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

person thbusch    schedule 19.10.2009