Цепочка конструктора в C ++ - PullRequest
       26

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

31 голосов
/ 08 сентября 2011

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

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

Функция-член вызывает функциюконструктор также попал под конструктор цепочки ??Просьба пролить свет на эту тему в C ++.

Ответы [ 5 ]

23 голосов
/ 22 октября 2015

C ++ 11 позволяет конструктор цепочки (частично).Эта функция называется " делегирование конструкторов ".Таким образом, в C ++ 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;
};

MSVC ++ 2013 выдает ошибку компиляции «C3511: вызов делегирующего конструктора должен быть единственным инициализатором-членом» для последнего примера кода.

20 голосов
/ 08 сентября 2011

Параграф в основном говорит это:

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
}
3 голосов
/ 08 сентября 2011

Это не то, что говорит текст.Он предлагает вашему конструктору вызвать функцию-член, которая является нормальной и законной.Это делается для того, чтобы избежать явного повторного вызова ctor и избежать дублирования кода между вашим ctor и функцией сброса.

Foo::Foo() {
  Init();
}

void Foo::Reset() {
  Init();
}

void Foo::Init() {
  // ... do stuff ...
}
0 голосов
/ 16 ноября 2013

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

Не рекомендуется вызывать конструкторы в функциях-членах, посколькусоздает объекты каждого производного класса.

0 голосов
/ 08 сентября 2011

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

Говоря в основном, не вызывайте конструктор, если вы не создаете ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...