Это неоднозначно или это прекрасно? - PullRequest
5 голосов
/ 29 января 2010

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

Ответы [ 6 ]

6 голосов
/ 29 января 2010

Нет, в этом случае нет никакой двусмысленности, но учтите следующее:

struct SCustomData {
//...
    void SetCode(int nCode)
    {
            //OOPS!!! Here we do nothing!
            //nCode = nCode;

            //This works but still error prone
            this->nCode = nCode;
    }
};

Вы должны обратить внимание на один из существующих стилей кодирования. Например, Общее правило именования в стилях кодирования Google C ++ или прочитайте превосходную книгу Херба Саттера и Андрея Александреску " Стандарты кодирования C ++: 101 правила, руководящие указания и лучшие практики ".

4 голосов
/ 29 января 2010

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

Прошло много времени с тех пор, как я написал C ++ в гневе, поэтому я догадываюсь, что будет делать следующее.
Вы ЗНАЕТЕ что это будет делать? Вы уверены?

class Noddy
{
    int* i;
    Noddy(int *i)
    : i(i)
    {
        if(i == NULL)
            i = new int;
    }
};
1 голос
/ 29 января 2010

Я бы сказал, что это прекрасно.

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

1 голос
/ 29 января 2010

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

struct SCustomData {
    int _nCode;
    int _nSum;
    int _nIndex;
    SCustomData(int nCode, int nSum, int nIndex)
        : _nCode(nCode), _nSum(nSum), _nIndex(nIndex)
    {}
};

// Alternatively
struct SCustomData {
    int _nCode;
    SCustomData(int nCode)
    {
        this->_nCode = nCode;
    }
};

Мне не нравится складывать переменные так, как это было написано в вопросе. Мне нравится экономить вертикальное пространство, и мне также легче читать слева направо. (Это мое личное предпочтение, а не обязательное правило или что-то в этом роде.)

1 голос
/ 29 января 2010

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

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

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

0 голосов
/ 29 января 2010

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

...