Подтвердить что ты не робот

Цепочка конструктора в С++

Мое понимание цепочки конструкторов заключается в том, что когда в классе (перегруженных конструкторах) существует несколько конструкторов, если один из них пытается вызвать другой конструктор, то этот процесс называется CONSTRUCTOR CHAINING, который не поддерживается в С++. Недавно я наткнулся на этот абзац, читая онлайн-материал... Это похоже на это...

Вы можете оказаться в ситуации, когда вы хотите написать функцию-член для повторной инициализации класса до значений по умолчанию. Поскольку у вас, вероятно, уже есть конструктор, который делает это, у вас может возникнуть соблазн попытаться вызвать конструктор из вашей функции-члена. Как уже упоминалось, вызовы конструктора цепочки являются незаконными в С++. Вы можете скопировать код из конструктора в свою функцию, что будет работать, но приведет к дублированию кода. Лучшее решение в этом случае - переместить код из конструктора в вашу новую функцию и заставить конструктор вызвать вашу функцию для выполнения инициализации данных.

Использует ли функция-член, вызывающая конструктор, цепочку конструкторов? Пожалуйста, пролишите немного света на эту тему в С++.

4b9b3361

Ответ 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

Я не уверен, что это (вызов конструктора из функции-члена) будет работать или нет, но это плохая практика. перемещение кода инициализации в новую функцию является логическим способом.

В основном говоря: не вызывайте конструктор, если вы не строите...