Por que não posso fazer isso?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Por que não posso fazer isso?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Respostas:
Você não pode inicializar a
e b
em B
porque eles não são membros B
. Eles são membros de A
, portanto, apenas A
podem inicializá-los. Você pode torná-los públicos e, em seguida, fazer a atribuição B
, mas essa não é uma opção recomendada, pois destruiria o encapsulamento. Em vez disso, crie um construtor em A
para permitir B
(ou qualquer subclasse de A
) inicializá-los:
class A
{
protected:
A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
// Change "protected" to "public" to allow others to instantiate A.
private:
int a, b; // Keep these variables private in A
};
class B : public A
{
public:
B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
{
}
};
a
e b
em B::B()
porque eles são privados. Você não pode inicializá-los porque eles não são membros de class B
. Se você os tornar públicos ou protegidos, poderá atribuí- los no corpo de B::B()
.
a
e b
..." 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 vez a
e b
são membros A
, eles são feitos para ser inicializado por A
construtores s, não por construtores de alguma outra classe (derivado ou não).
Experimentar:
class A
{
int a, b;
protected: // or public:
A(int a, int b): a(a), b(b) {}
};
class B : public A
{
B() : A(0, 0) {}
};
De alguma forma, ninguém listou a maneira mais simples:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
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
e protected
membros da classe base.
B
for alocada e, em seguida, será atribuído dentro do B
construtor de. Mas também acho que o compilador ainda pode otimizar isso.
class A
, não podemos confiar a
e b
ser inicializados. Qualquer implementação de class C : public A
, por exemplo, pode se esquecer de chamar a=0;
e deixar a
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.
# include<stdio.h>
# include<iostream>
# include<conio.h>
using namespace std;
class Base{
public:
Base(int i, float f, double d): i(i), f(f), d(d)
{
}
virtual void Show()=0;
protected:
int i;
float f;
double d;
};
class Derived: public Base{
public:
Derived(int i, float f, double d): Base( i, f, d)
{
}
void Show()
{
cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
}
};
int main(){
Base * b = new Derived(10, 1.2, 3.89);
b->Show();
return 0;
}
É 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.
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
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:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
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.
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 caso B() : 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áticos