Цепочка конструктора в С++
Мое понимание цепочки конструкторов заключается в том, что когда в классе (перегруженных конструкторах) существует несколько конструкторов, если один из них пытается вызвать другой конструктор, то
этот процесс называется CONSTRUCTOR CHAINING, который не поддерживается в С++.
Недавно я наткнулся на этот абзац, читая онлайн-материал... Это похоже на это...
Вы можете оказаться в ситуации, когда вы хотите написать функцию-член для повторной инициализации класса до значений по умолчанию. Поскольку у вас, вероятно, уже есть конструктор, который делает это, у вас может возникнуть соблазн попытаться вызвать конструктор из вашей функции-члена. Как уже упоминалось, вызовы конструктора цепочки являются незаконными в С++. Вы можете скопировать код из конструктора в свою функцию, что будет работать, но приведет к дублированию кода. Лучшее решение в этом случае - переместить код из конструктора в вашу новую функцию и заставить конструктор вызвать вашу функцию для выполнения инициализации данных.
Использует ли функция-член, вызывающая конструктор, цепочку конструкторов?
Пожалуйста, пролишите немного света на эту тему в С++.
Ответы
Ответ 1
В параграфе в основном говорится следующее:
class X
{
void Init(params) {/*common initing code here*/ }
X(params1) { Init(someParams); /*custom code*/ }
X(params2) { Init(someOtherParams); /*custom code*/ }
};
Вы также не можете вызвать конструктор из функции-члена. Может показаться вам, что вы это сделали, но это иллюзия:
class X
{
public:
X(int i):i(i){}
void f()
{
X(3); //this just creates a temprorary - doesn't call the ctor on this instance
}
int i;
};
int main()
{
using std::cout;
X x(4);
cout << x.i << "\n"; //prints 4
x.f();
cout << x.i << "\n"; //prints 4 again
}
Ответ 2
С++ 11 позволяет связывать конструктор (частично). Эта функция называется делегирование конструкторов". Итак, в С++ 11 вы можете сделать следующее
class Foo
{
public:
Foo(int a) : Foo() { _a = a; }
Foo(char* b) : Foo() { _b = b; }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
Однако существует серьезное ограничение того, что конструктору, вызывающему другой конструктор, не разрешается инициализировать другие члены. Поэтому с конструктором делегирования вы не можете сделать следующее:
class Foo
{
public:
Foo(int a) : Foo(), _a(a) { }
Foo(char* b) : Foo(), _b(b) { }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
MSVС++ 2013 дает ошибку компиляции "C3511: вызов для конструктора делегирования должен быть единственным инициализатором-членом" для последнего примера кода.
Ответ 3
Это не то, что говорится в тексте. Это предполагает, что ваш конструктор вызывает функцию-член, которая является нормальной и законной. Это делается для того, чтобы избежать явного вызова ctor еще раз и избежать дублирования кода между вашим ctor и функцией reset.
Foo::Foo() {
Init();
}
void Foo::Reset() {
Init();
}
void Foo::Init() {
// ... do stuff ...
}
Ответ 4
когда мы вызываем конструктор из функции-члена, он временно создает объект своего типа.
в случае, если мы вызываем функцию производного класса, тогда все родительские конструкторы также выполняются и уничтожаются с использованием деструктора, когда функция выходит за пределы области видимости.
не является хорошей практикой для вызова конструкторов в функциях-членах, поскольку он создает объекты каждого производного класса.
Ответ 5
Я не уверен, что это (вызов конструктора из функции-члена) будет работать или нет, но это плохая практика. перемещение кода инициализации в новую функцию является логическим способом.
В основном говоря: не вызывайте конструктор, если вы не строите...