Chamando o Construtor Sobrecarregado de uma Classe Base Virtual
Existe uma maneira (prática) de ignorar a ordem de chamada do construtor normal (virtual)?
Exemplo:
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;
}
Resultado:
chamando A ()
chamando B (int)
chamando C (int)
chamando D (int)
O que eu quero ter é algo como:
chamando A (int)
chamando B (int)
chamando C (int)
chamando D (int)
Como você vê, há herança virtual envolvida, o que leva o construtor de D a chamar o construtor de A primeiro, mas como nenhum parâmetro é fornecido, ele chama A (). Tem oconst int i que precisa de inicialização, então eu tenho um problema.
O que eu gostaria de fazer é ocultar os detalhes da herança de C, é por isso que estou procurando uma maneira de evitar chamar A (i) na lista de inicialização do construtor de D (e todos os derivados). [edit] Nesse caso específico, posso assumir que existem apenas classes filho de herança única não virtual de C (como D é um). [/editar]
[editar]
As classes base virtuais são inicializadas antes de qualquer classe base não virtual ser inicializada, portanto, apenas a classe mais derivada pode inicializar classes base virtuais. - James McNellis
Esse é exatamente o ponto, eunão deseja que a classe mais derivada chame o construtor da classe base virtual.[/editar]
Considere a seguinte situação (não representado no exemplo de código acima):
A
/ \
B0 B1
\ /
C
|
D
Entendo por que C precisa chamar o ctor de A (ambiguidade) quando você instancia C, mas por que D precisa chamá-lo ao instanciar D?