Рассмотрим следующий класс C ++:
struct Point
{
int x;
int y;
explicit Point() =default; // 1
explicit Point(int x_, int y_): x(x_), y(y_) { } // 2
};
Второй конструктор полезен для создания Point
с конкретными x
а также y
ценности. Первый существует, так что я могу по умолчанию построить Point
, Тем не менее, для эффективности, это default
Эд и не устанавливает x
а также y
в ноль. Если бы я хотел установить все члены на ноль, у меня мог бы быть другой конструктор:
explicit Point(int val) : x(val), y(val) { } // 3
Таким образом, я могу выбрать инициализацию по умолчанию Point
или инициализируйте его, установив все члены на ноль:
Point p1; // Don't initialize members.
Point p2(0); // Initialize all members to zero.
Проблема с третьим конструктором заключается в том, что я могу передать любое значение, а не только ноль. Например:
Point p(1); // Both x and y set to 1! Is this the intent? If so,
// probably should have used Point p(1, 1) instead.
Другим способом было бы иметь специальный тип, который представляет нулевое значение или значение по умолчанию, и передать его конструктору:
explicit Point(Default) : x(0), y(0) { } // 4
куда Default
можно определить просто как:
struct Default { };
Затем я могу контролировать, когда я хочу Point
быть инициализированным со значениями по умолчанию:
Point p1; // Don't initialize members.
Point p2(Default()); // Initialize members with default values.
Какой метод будет считаться лучшим, метод с дозорным типом Default
(№ 4), или конструктор, который принимает одно значение и инициализирует все члены этим значением (№ 3)? Каковы плюсы / минусы двух методов? Или есть другой лучший механизм для этого?
Редактировать: Обратите внимание, что этот простой класс был выбран для иллюстрации; в действительности может быть гораздо больше членов, которым необходимо учитывать определенные значения по умолчанию «Инициализирован».
Сделайте свою жизнь проще, создайте простые структуры данных, такие как эти агрегаты:
struct Point
{
int x;
int y;
};
Теперь вы можете использовать агрегатную инициализацию:
Point p; // members uninitialized
Point p{}; // members set to 0
Point p{1,2}; // members set to 1,2
Наиболее распространенная практика, которую я вижу для этого, заключается в реализации конструктора без аргументов со списком инициализации, который содержит для каждого члена класса любое значение по умолчанию, которое вы хотите.
Point(): x(0), y(0) { }
Причиной этого является то, что вы, вероятно, никогда не захотите создавать экземпляр объекта, не инициализируя членов каким-либо известным значением, поэтому вы на самом деле не хотите, чтобы этот конструктор по умолчанию существовал.
Другой вариант заключается в использовании:
struct Point
{
int x;
int y;
explicit Point(int x_ = 0, int y_ = 0): x(x_), y(y_) {}
};
Point p1; // 0, 0
Point p2(1); // 1, 0
Point p3(1, 10); // 1, 10