Por que não posso fazer isso?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
c++
inheritance
Amrhassan
fonte
fonte
Respostas:
Você não pode inicializar
a
eb
emB
porque eles não são membrosB
. Eles são membros deA
, portanto, apenasA
podem inicializá-los. Você pode torná-los públicos e, em seguida, fazer a atribuiçãoB
, mas essa não é uma opção recomendada, pois destruiria o encapsulamento. Em vez disso, crie um construtor emA
para permitirB
(ou qualquer subclasse deA
) inicializá-los:fonte
a
eb
emB::B()
porque eles são privados. Você não pode inicializá-los porque eles não são membros declass B
. Se você os tornar públicos ou protegidos, poderá atribuí- los no corpo deB::B()
.a
eb
..." e mudei para "Você não pode inicializar ..." sem ter certeza de que o resto da frase fazia sentido. Postagem editada.Deixando de lado o fato de que eles são
private
, uma veza
eb
são membrosA
, eles são feitos para ser inicializado porA
construtores s, não por construtores de alguma outra classe (derivado ou não).Experimentar:
fonte
De alguma forma, ninguém listou a maneira mais simples:
Você não pode acessar membros base na lista de inicializadores, mas o próprio construtor, assim como qualquer outro método de membro, pode acessar
public
eprotected
membros da classe base.fonte
B
for alocada e, em seguida, será atribuído dentro doB
construtor de. Mas também acho que o compilador ainda pode otimizar isso.class A
, não podemos confiara
eb
ser inicializados. Qualquer implementação declass C : public A
, por exemplo, pode se esquecer de chamara=0;
e deixara
não inicializado.class A { int a = 0;};
) ou no construtor da classe base. As subclasses ainda podem reinicializá-los em seu construtor conforme necessário.É um exemplo de trabalho no caso de você desejar inicializar os membros de dados da classe Base presentes no objeto da classe Derived, enquanto você deseja enviar esses valores de interface por meio da chamada do construtor da classe Derived.
fonte
Embora isso seja útil em casos raros (se não fosse o caso, o idioma teria permitido diretamente), dê uma olhada na Base de idioma dos membros . Não é uma solução livre de código, você teria que adicionar uma camada extra de herança, mas dá conta do recado. Para evitar o código clichê, você pode usar a implementação de boost
fonte
Por que você não pode fazer isso? Porque a linguagem não permite que você inicialize os membros da classe base na lista de inicializadores da classe derivada.
Como você pode fazer isso? Como isso:
fonte
Se você não especificar a visibilidade para um membro da classe, o padrão é "privado". Você deve tornar seus membros privados ou protegidos se quiser acessá-los em uma subclasse.
fonte
Classes agregadas, como A em seu exemplo (*), devem ter seus membros públicos e não ter construtores definidos pelo usuário. Eles são inicializados com a lista de inicializadores, por exemplo,
A a {0,0};
ou no seu casoB() : A({0,0}){}
. Os membros da classe agregada básica não podem ser inicializados individualmente no construtor da classe derivada.(*) Para ser preciso, como foi corretamente mencionado, o original
class A
não é um agregado devido a membros privados não estáticosfonte