Есть ли более простой способ для конструктора класса указать, что все члены встроенного типа должны быть инициализированы нулями?
Этот фрагмент кода появился в другом посте:
struct Money
{
double amountP, amountG, totalChange;
int twenty, ten, five, one, change;
int quarter, dime, nickel, penny;
void foo();
Money() {}
};
и оказалось, что проблема была в том, что объект был создан с помощью Money mc;
и переменные были неинициализированы.
Рекомендованным решением было добавить следующий конструктор:
Money::Money()
: amountP(), amountG(), totalChange(),
twenty(), ten(), five(), one(), change()
quarter(), dime(), nickel(), penny()
{
}
Тем не менее, это некрасиво и не удобно для обслуживания. Было бы легко добавить другую переменную-член и забыть добавить ее в длинный список в конструкторе, что может привести к трудным для обнаружения ошибкам в течение нескольких месяцев, когда неинициализированная переменная внезапно перестанет получать 0
случайно.
Вы можете использовать подобъект для массовой инициализации. Член работает, но тогда вам нужно квалифицировать весь доступ. Так что наследование лучше
struct MoneyData
{
double amountP, amountG, totalChange;
int twenty, ten, five, one, change;
int quarter, dime, nickel, penny;
};
struct Money : MoneyData
{
void foo();
Money() : MoneyData() {} /* value initialize the base subobject */
};
Демонстрация (размещение new
используется, чтобы убедиться, что память не равна нулю перед созданием объекта): http://ideone.com/P1nxN6
Контраст с небольшим изменением кода в вопросе: http://ideone.com/n4lOdj
В обеих вышеперечисленных демонстрациях double
члены удаляются, чтобы избежать возможных недействительных / NaN-кодировок.
Для чего-то, работающего в C ++ 98, вы можете использовать Boost’s value_initialized
: (живой пример)
#include <boost/utility/value_init.hpp>
...
struct Money
{
boost::value_initialized<double> amountP, amountG, totalChange;
boost::value_initialized<int> twenty, ten, five, one, change;
boost::value_initialized<int> quarter, dime, nickel, penny;
void foo();
Money() {/*every member is 0*/}
};
Вы можете использовать конструктор по умолчанию следующим образом
Money m = {};
Или вы можете установить инициализацию членов данных внутри определения класса:
struct Money
{
double amountP = 0.0, amountG = 0.0, totalChange = 0.0;
int twenty = 0, ten = 0, five - 0, one = 0, change = 0;
int quarter = 0, dime = 0, nickel = 0, penny = 0;
void foo();
Money() {}
};