una tipos sobrecarga qué que metodo ejemplos definicion constructores clase c++ gcc c++11 ctor-initializer

c++ - tipos - Inicialización de miembros al usar un constructor delegado



qué es un constructor en c++? (1)

Empecé probando el estándar C ++ 11 y encontré this pregunta que describe cómo llamar a tu ctor desde otro ctor en la misma clase para evitar tener un método init o similar. Ahora estoy intentando lo mismo con un código que se ve así:

hpp:

class Tokenizer { public: Tokenizer(); Tokenizer(std::stringstream *lines); virtual ~Tokenizer() {}; private: std::stringstream *lines; };

cpp:

Tokenizer::Tokenizer() : expected(''='') { } Tokenizer::Tokenizer(std::stringstream *lines) : Tokenizer(), lines(lines) { }

Pero esto me está dando el error: In constructor ''config::Tokenizer::Tokenizer(std::stringstream*)'': /path/Tokenizer.cpp:14:20: error: mem-initializer for ''config::Tokenizer::lines'' follows constructor delegation He intentado mover la parte de Tokenizer () primero y último en la lista, pero eso no ayudó.

¿Cuál es la razón detrás de esto y cómo debería solucionarlo? Intenté mover las lines(lines) al cuerpo con this->lines = lines; en su lugar y funciona bien. Pero me gustaría poder usar la lista de inicializadores.

¡Gracias por adelantado!


Cuando delega la inicialización de miembro a otro constructor, se supone que el otro constructor inicializa el objeto por completo , incluidos todos los miembros (es decir, incluido el miembro de lines en su ejemplo). Por lo tanto, no puede inicializar a ninguno de los miembros nuevamente.

La cita relevante del Estándar es (énfasis mío):

(§12.6.2 / 6) Un mem-initializer-list puede delegar en otro constructor de la clase del constructor usando cualquier class-or-decltype que denote la propia clase del constructor. Si un mem-initializer-id designa la clase del constructor, será el único mem-initializer ; el constructor es un constructor delegante, y el constructor seleccionado por el es el constructor de destino. [...]

Puede solucionar esto definiendo la versión del constructor que toma argumentos primero :

Tokenizer::Tokenizer(std::stringstream *lines) : lines(lines) { }

y luego define el constructor por defecto usando la delegación:

Tokenizer::Tokenizer() : Tokenizer(nullptr) { }

Como regla general, debe especificar completamente la versión del constructor que toma la mayor cantidad de argumentos y luego delegar desde las otras versiones (utilizando los valores predeterminados deseados como argumentos en la delegación).