¿Existe alguna forma (práctica) de eludir el orden de llamada del constructor normal (virtual)?Llamar al constructor sobrecargado de una clase base virtual
Ejemplo:
class A
{
const int i;
public:
A()
: i(0)
{ cout << "calling A()" << endl; }
A(int p)
: i(p)
{ cout << "calling A(int)" << endl; }
};
class B
: public virtual A
{
public:
B(int i)
: A(i)
{ cout << "calling B(int)" << endl; }
};
class C
: public B
{
public:
C(int i)
: A(i), B(i)
{ cout << "calling C(int)" << endl; }
};
class D
: public C
{
public:
D(int i)
: /*A(i), */ C(i)
{ cout << "calling D(int)" << endl; }
};
int main()
{
D d(42);
return 0;
}
de salida:
llamante A()
llamando B (int)
llamando C (int)
llamando D (int)
lo que quiero es tener algo como:
llamar A (int)
llamando B (int)
llamando C (int)
llamando D (int)
Como ve, hay una herencia virtual involucrada, que lleva al constructor de D a llamar primero al constructor de A, pero como no se proporciona ningún parámetro, llama a A(). Está el const int i que necesita inicialización, así que tengo un problema.
Lo que me gustaría hacer es ocultar los detalles de herencia de C, es por eso que estoy buscando una forma de evitar llamar a A (i) en la lista de inicialización del constructor de D's (y cada derivada). [edit] En este caso específico, puedo suponer que solo hay clases secundarias de herencia única no-virtuales de C (como D es uno). [/ Editar]
[editar]
clases base virtuales se inicializan antes de cualquier clases base no virtuales se inicializan, por lo que sólo la clase más derivada puede inicializar clases base virtuales. - James McNellis
eso es exactamente el punto, yo No quieren que la clase más derivada para llamar al constructor de la clase base virtual. [/ editar]
Considere la siguiente situación (no representados en el ejemplo de código anterior):
A
/\
B0 B1
\/
C
|
D
entiendo por qué C tiene que llamar al ctor de A (ambigüedad) cuando instanciar C, pero ¿por qué D tiene que invocarlo al crear instancias de D?
No creo que su ejemplo de código coincida con el resultado que proporciona. ¿Estás seguro de que has creado d con la instrucción "D d"? ? –
sry, olvidé el parámetro ... es D d (42) ahora. Gracias. – dyp
Ok, eso parece más justo :-) ¿Puedo preguntar por qué quieres usar la arquitectura de "diamante temido"? ¿No puedes reorganizar tu código de alguna otra manera? –