initialize enclosed brace c++ constructor specifications constructor-chaining

enclosed - Constructor de encadenamiento en C++



initialize vector c++ 11 (5)

Mi comprensión del encadenamiento de constructores es que, cuando hay más de un constructor en una clase (constructores sobrecargados), si uno de ellos intenta llamar a otro constructor, este proceso se llama CONSTRUCTOR CHAINING, que no se admite en C ++. Recientemente me encontré con este párrafo mientras leía material en línea ... Es así ...

Es posible que se encuentre en la situación en la que desea escribir una función miembro para reinicializar una clase a los valores predeterminados. Debido a que probablemente ya tenga un constructor que hace esto, puede sentirse tentado a intentar llamar al constructor desde su función miembro. Como se mencionó, las llamadas de constructor de cadenas son ilegales en C ++. Podría copiar el código del constructor en su función, lo que funcionaría, pero conducir a un código duplicado. La mejor solución en este caso es mover el código del constructor a su nueva función, y hacer que el constructor llame a su función para realizar el trabajo de inicialización de los datos.

¿Una función miembro que llama al constructor también se incluye en el encadenamiento de constructores? Por favor arroje algo de luz sobre este tema en C ++.


C ++ 11 permite el encadenamiento de constructores (parcialmente). Esta característica se llama " constructores delegantes ". Así que en C ++ 11 puedes hacer lo siguiente

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; };

Sin embargo, existe una grave limitación de que un constructor que llama a otro constructor no tiene permiso para inicializar a otros miembros. Entonces no puedes hacer lo siguiente con un constructor delegante:

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 da error de compilación "C3511: una llamada a un constructor delegante será el único inicializador de miembro" para el último código de ejemplo.


El párrafo básicamente dice esto:

class X { void Init(params) {/*common initing code here*/ } X(params1) { Init(someParams); /*custom code*/ } X(params2) { Init(someOtherParams); /*custom code*/ } };

Tampoco puede llamar a un constructor desde una función miembro. Puede parecerte que lo has hecho, pero eso es una ilusión:

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 }


Eso no es lo que dice el texto. Está sugiriendo que su constructor llame a una función miembro que es normal y legal. Esto es para evitar que se vuelva a llamar explícitamente al ctor y para evitar la duplicación de código entre su ctor y la función de reinicio.

Foo::Foo() { Init(); } void Foo::Reset() { Init(); } void Foo::Init() { // ... do stuff ... }


No estoy seguro de si (llamar a un constructor desde una función miembro) funcionará o no, pero es una mala práctica. mover el código de inicialización a una nueva función es la forma lógica.

Básicamente diciendo: No llames al constructor a menos que estés construyendo ...


cuando llamamos al constructor desde una función miembro, entonces creará temporalmente un objeto de su tipo. en caso de que estemos llamando a la función de clase derivada, todos los constructores principales también se ejecutarán y destruirán utilizando el destructor una vez que la función salga del alcance.

No es una buena práctica llamar a los constructores en funciones miembro, ya que crea objetos de todas las clases derivadas.