Construtores herdeiros
porque é que este código:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
};
int main(void)
{
B *b = new B(5);
delete b;
}
resulta nestes erros:
main.cpp: In function ‘int main()’: main.cpp:13: error: no matching function for call to ‘B::B(int)’ main.cpp:8: note: candidates are: B::B() main.cpp:8: note: B::B(const B&)A B não devia herdar o construtor da A?
(Isto é usar o gcc)
6 answers
Em C++03, os construtores padrão não podem ser herdados e você precisa herdá-los manualmente um a um, chamando a implementação base por conta própria. Se o seu compilador suporta a norma C++11, existe uma herança Construtora. Para mais ver Wikipedia C++11 article . Com o novo padrão você escreve:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
using A::A;
};
O compilador cria um construtor default (um sem argumentos) e um construtor default copy (um com um argumento que é uma referência ao mesmo tipo). Mas se você quer um construtor que vai aceitar um int, você tem que defini-lo explicitamente.
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
public:
explicit B(int x) : A(x) { }
};
UPDATE: Em C++11, Os construtores podem ser herdados. Veja a resposta de Suma para detalhes.
Você tem que definir explicitamente o construtor em B e chamar explicitamente o construtor para o pai.
B(int x) : A(x) { }
Ou
B() : A(5) { }
Se assim o escolheres, ainda te podes atirar no pé herdando Construtores numa classe derivada na qual defines variáveis de novos membros que necessitam de inicialização:
struct B1 {
B1(int) { }
};
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test()
{
D1 d(6); // Oops: d.x is not initialized
D1 e; // error: D1 has no default constructor
}
O código correcto é
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
public:
B(int a):A(a){
}
};
main()
{
B *b = new B(5);
delete b;
}
O erro é que a Classe B/C B não tem construtor de parâmetros e, em segundo lugar, deve ter inicializador de classes de base para chamar o construtor do construtor de Parâmetros de Base
template <class... T> Derived(T... t) : Base(t...) {}