Como dijeron varias personas que respondieron, no puede retrasar la invocación de un constructor de clase base, pero Konrad has given a good answer que bien podría resolver su problema. Sin embargo, esto tiene sus desventajas (por ejemplo, cuando necesita inicializar varias funciones con valores cuyos cálculos comparten resultados intermedios), así que para completar, aquí hay otra forma de resolver el problema del orden de inicialización fijo, por usando .
Dado el orden fijo de inicialización, si tiene control sobre la clase derivada (¿y de qué otro modo podría venir a jugar con uno de sus ctors?), Puede colarse en una base privada por lo que va a ser inicializado antes de la otra base, que luego puede ser inicializado 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 usarlo, todas sus cosas son privadas, también, con amistad explícita que solo otorga acceso a the_class
. Sin embargo, dado que se encuentra primero en la lista de la clase base, se construirá de manera confiable antes de the_other_base_class
, por lo que lo que se calcula se puede usar para inicializar eso.
Un buen comentario en la lista de la clase base con suerte evita que otros rompan cosas al refactorizar.
Gracias, no pensé en llamar a una función, así que funcionará pero va a ser un poco complicado porque el constructor tiene 2 parámetros. Aceptaré esta respuesta cuando pueda (a menos que salga una mejor, por supuesto). Por cierto, tienes razón sobre no poder hacer esto en Java y C#, pensé que era posible en Java porque se hace usando 'super (...)' en el cuerpo del método, pero ahora me doy cuenta de que debe ser la primera línea. – placeholder
+1 Debería establecer some_function() static para documentar el hecho de que no utiliza ninguna de las variables de instancia de la clase (que no se han inicializado). –
Interesante, nunca visto eso hecho antes. Supongo que la función llamada puede ser una función de clase derivada. – PatrickV