Polimorfismo e ponteiros para matrizes [duplicado]
-
05-07-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
Eu tenho uma classe A:
class A
{
public:
virtual double getValue() = 0;
}
E uma classe B:
class B : public A
{
public:
virtual double getValue() { return 0.0; }
}
E, em seguida, em main () eu faço:
A * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //This, or any other index besides 0, causes the program to quit
Se em vez disso, fazer:
B * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //Everything else works fine too
Tudo compila bem, mas parece que há algo de errado com meu polimorfismo talvez? Estou intrigado.
Solução
Você não pode matrizes tratar polymorphically, por isso, enquanto new B[100]
cria um array de objetos B
e retorna um ponteiro para a matriz - ou equivalentemente o primeiro elemento da matriz - e enquanto ele é válido para atribuir este ponteiro para um ponteiro para uma classe base, não é válido para tratar isso como um ponteiro para um array de objetos A
.
A principal razão que você não pode é que (geralmente) derivado objetos são um tamanho diferente para suas classes base, de modo a tentar aceder a matriz como uma matriz de objetos da classe base não vai usar o deslocamento correto para obter um ponteiro para o próximo subobjecto classe base do próximo membro da matriz classe derivada.
Outras dicas
Não há nenhum problema com o polymrphism mas com a forma como você está lidando com a memória. O operador [] avançará-lo através da matriz pelo sizeof (A) bytes, no primeiro caso e o sizeof (B) bytes no segundo caso. Como os objetos são do tipo B a A * não está apontando para o local correto na memória.
Aqui é uma outra maneira de olhar para ele
char * var;
var = (char*) new B[100];
std::cout << ((A*)var[0]).getValue(); //This works fine
std::cout << ((A*)var[1]).getValue(); //This will fail
std::cout << ((A*)var[sizeof(B)]).getValue(); // should work
Você não alocar os objetos na matriz:
for (int i=0;i<100;i++)
var[i] = new B;
(embora possa ser misturando C ++ e C #)