Переменные-члены указателя структуры возвращают неправильное число.
Вот объявление структуры:
struct Obj {
int val;
Obj(int val) { val = val; }
};
Вот где это становится забавным:
Obj* cool = new Obj(4);
cout << cool->val; // outputs a number that's not 4
cout << (cool->val == 4); // prints 0... interesting
Вы никогда не инициализируете Obj::val
таким образом, значение — это то, что происходит в этой ячейке памяти в момент создания экземпляра Obj
,
struct Obj {
int val; // (A)
Obj(int val) { // (C)
val = val; // (B)
}
};
Внутри конструктора Obj
названный параметр val
прячет Данные членов названный val
; другими словами, вы присваиваете значение аргумента с именем val
к аргументу по имени val
,
Стандарт гласит, что переменная, объявленная в более узкой области видимости, чем предыдущая, будет эффективно скрывать старую.
Это означает, что, поскольку аргумент val
в (В) находится в более узком объеме, чем (), в точке (С) компилятор думает, что вы ссылаетесь на аргумент.
У вас есть несколько вариантов решения этой проблемы
this->val = val; // (A)
Obj::val = val; // equivalent
Obj (int val) : val (val) { } // (B)
Obj (int foo) { val = foo; } // (C)
), используйте this->val
явно указать, что вы хотите присвоить значение члену данных Obj
В), использовать мем-инициализатор где Obj::val
не будет скрыто именем аргумента
С), измените имя вашего аргумента
Вне Предлагаемые решения, решение помечено (В) является предпочтительным.
Это называется с помощью мем-инициализатор, и инициализирует член вал со значением аргумента вал непосредственно по вызову конструктора; вместо этого сначала необходимо инициализировать по умолчанию, а затем присвоить значение.
Рекомендуется также не иметь аргументов с тем же именем, что и переменные-члены, так как это может быть подвержено ошибкам, если забыть о Имя скрытие.
Общий дизайн — это префикс каждого Данные членов с m_
явно указать, что таковой действительно является элемент экземпляра, например, в следующем фрагменте:
struct Obj {
Obj(int val) : m_val (val) { }
int m_val;
};
Это:
Obj(int val) { val = val; }
просто присваивает параметр себе и оставляет переменную-член, содержащую мусор. Тебе нужно:
Obj(int val) : val(val) {}
или (если вам действительно нужно назначить, а не инициализировать):
Obj(int val) { this->val = val; }
или же:
Obj(int the_val) { val = the_val; }
Вы можете рассмотреть возможность использования соглашения об именах для членов:
int m_val;
Obj(int val) : m_val(val) {}