В C ++ 11 одним из вариантов может быть делегирование конструктора, когда один конструктор просто вызывает один из других конструкторов, чтобы избежать дублирования кода.
Вот как это выглядит:
class A {
public:
A(int,int,double);
A(int,int);
A(double);
A();
private:
...
};
A::A(int a,int b,double c) {
// the real work to initialize the class
}
// A(int,int) delegates to A(int,int,double), passing along a
// default value for the double
A::A(int a,int b) : A(a,b,0.0) {}
A::A(double c) : A(1,2,c) {} // A(double) delegates to A(int,int,double)
A::A() : A(1.0) {} // A() delegates to A(double)
Убедитесь, что вы не создаете никаких петель.Также обычно вы хотите, чтобы один конструктор выполнял большую часть реальной работы, в то время как другие просто собирали значения, которые они хотят передать этому конструктору.Мы назовем это «назначенным конструктором».Назначенный конструктор должен быть тем, который принимает большинство параметров и не использует никаких значений по умолчанию.В конце концов все конструкторы должны вызывать назначенный конструктор, прямо или косвенно.
Обратите внимание на шаблон: конструкторы, которые используют некоторые значения по умолчанию, передают эти значения по умолчанию конструкторам, которые используют меньше значений по умолчанию, пока вы не получите функцию без значений по умолчанию.совсем.Это противоположно тому, что вы пытаетесь сделать с помощью метода init_members()
.У вас есть функция, которая устанавливает все значения по умолчанию, а затем вы пытаетесь переопределить некоторые из них.Если вы не можете использовать функции C ++ 11, вам лучше эмулировать назначенный шаблон конструктора: init_members()
будет вашим назначенным инициализатором и не будет иметь никаких значений по умолчанию.Вы можете использовать метод инициализатора для каждого конструктора, который принимает заданные аргументы и добавляет несколько значений по умолчанию, чтобы вызвать другую init_members
перегрузку.
Однако одна проблема с назначенным инициализатором / конструктором заключается в том, что значения по умолчаниюразбросаны повсюду.Другой вариант в C ++ 11 помимо делегирования - «инициализация в классе», которая позволяет собирать все значения по умолчанию.
class A {
public:
A(int,int,double);
A(int,int);
A(double);
A();
private:
int a = 1,b = 2; // in-class initialization gathers all the defaults together
double c = 1.0;
};
Учитывая вышеизложенное, все конструкторы автоматически инициализируют значения элементов вэти значения по умолчанию, если вы явно не инициализируете его чем-то другим в этом конструкторе.
A::A(int a,int b,double c) : a(a), b(b), c(c) {}
A::A(int a,int b) : a(a), b(b) {} // member c is automatically initialized to 1.0
A::A(double c) : c(c) {} // members a and be are automatically initialized to 1 and 2
A::A() {}; // all members are initialized with their in-class values.
Вот пример использования init_members()
:
class A {
public:
A(int a,int b,double c) { init_members(a,b,c); }
A(int a,int b) { init_members(a,b); }
A(double c) {init_members(c);}
A() { init_members(); }
private:
void init_members(int,int,double) { ... }
void init_members(int a,int b) { init_members(a,b,1.0); }
void init_members(double c) { init_members(1,2,c); }
void init_members() { init_members(1.0); }
...
};
Это значение метода инициализирует члены передМожно вызвать init_members()
, поэтому члены инициализируются дважды.Я не уверен, что есть способ исправить это в C ++ 03.