c++ constructor delayed-execution

Llame a un constructor de clase base más tarde(no en la lista de inicializadores) en C++



delayed-execution (5)

¿Hay alguna manera de que pueda llamarlo más tarde en lugar de hacerlo en la lista de inicializadores?

No, no puedes. El constructor de la clase base debe llamarse en la lista de inicializadores, y debe llamarse primero.

De hecho, si lo omites allí, el compilador simplemente agregará la llamada implícitamente.

Creo que esto se puede hacer en Java y C #, pero no estoy seguro acerca de C ++.

Ni C # ni Java lo permiten.

Sin embargo, lo que puede hacer es llamar a un método como un argumento de la llamada del constructor de la clase base. Esto se procesa luego ante el constructor:

class Derived { public: Derived() : Base(some_function()) { } private: static int some_function() { return 42; } };

Estoy heredando una clase y me gustaría llamar a uno de sus constructores. Sin embargo, tengo que procesar algunas cosas (que no requieren nada de la clase base) antes de llamarlo. ¿Hay alguna manera de que pueda llamarlo más tarde en lugar de hacerlo en la lista de inicializadores? Creo que esto se puede hacer en Java y C #, pero no estoy seguro acerca de C ++.

Los datos que necesito transmitir al constructor no se pueden reasignar más tarde, por lo que no puedo llamar a un constructor predeterminado e inicializarlo más tarde.


Como dijeron varias personas que respondieron, no puede retrasar la invocación de un constructor de clase base, pero Konrad ha dado una buena respuesta que podría resolver su problema. Sin embargo, esto tiene sus inconvenientes (por ejemplo, cuando necesita inicializar varias funciones con valores cuyos cálculos comparten resultados intermedios), así que para completar, aquí hay otra manera de resolver el problema del orden de inicialización fijo, usándolo .

Dado el orden fijo de inicialización, si tiene control sobre la clase derivada (¿y de qué otra forma podría jugar con uno de sus ctors?), Puede colarse en una base privada para que se inicialice antes que el otro base, que luego se puede inicializar con los valores ya calculados de la base privada:

class my_dirty_little_secret { // friend class the_class; public: my_dirty_little_secret(const std::string& str) { // however that calculates x, y, and z from str I wouldn''t know } int x; std::string y; float z; }; class the_class : private my_dirty_little_secret // must be first, see ctor , public the_other_base_class { public: the_class(const std::string str) : my_dirty_little_secret(str) , the_other_base_class(x, y, z) { } // ... };

La clase my_dirty_little_secret es una base privada por lo que los usuarios de the_class no pueden usarla, todas sus cosas también son privadas, con una amistad explícita que solo le the_class acceso a the_class . Sin embargo, como se incluye primero en la lista de clases base, se construirá de manera confiable antes de the_other_base_class , por lo que cualquier cosa que calcule se puede usar para inicializar eso.
Un buen comentario en la lista de clases base con suerte evita que otros rompan cosas al refactorizar.


En mi humilde opinión no creo que sea posible aplazar la llamada al constructor de la clase base de la forma que mencionaste.


Wow, todos fuimos jóvenes una vez. Esta respuesta no funcionará, así que no la uses. Contenido dejado para fines históricos.

Si tiene control total sobre la clase base, recomendaría agregar un método protegido para realizar la inicialización de la clase, hacerlo virtual y colocar los detalles de implementación de la clase derivada antes de que llame a su base:

class Base { public: Base() { Initialize(); } protected: virtual void Initialize() { //do initialization; } }; class Derived : Base { public: Derived() : Base() { } protected: virtual void Initialize() { //Do my initialization //call base Base::Initialize(); } };


struct base{ base(int x){} }; struct derived : base{ derived(int x) : base(x){} };

Así es como se invocan los constructores de clases base en C ++ desde la lista de inicialización de la clase derivada.