Usando uma classe abstrata para implementar uma pilha de elementos da classe derivada
-
22-09-2019 - |
Pergunta
Eu tenho que fazer isso para uma palestra básica de C ++ na minha universidade, então apenas para ficar claro: eu teria usado o STL se pudesse.
O problema: eu tenho uma classe chamada "shape3d" da qual eu derivei as classes "cubo" e "esfera". Agora eu tenho que implementar "Shape3D_Stack", o que significa ser capaz de manter objetos dos tipos "cubo" e "esfera". Eu usei matrizes para isso e funcionou muito bem quando tentei fazê -lo com uma pilha de INTs. Eu tentei fazer assim:
shape3d_stack.cpp:
15 // more stuff
16
17 shape3d_stack::shape3d_stack (unsigned size) :
18 array_ (NULL),
19 count_ (0),
20 size_ (size)
21 { array_ = new shape3d[size]; }
22
23 // more stuff
Mas, infelizmente, o compilador me diz:
g++ -Wall -O2 -pedantic -I../../UnitTest++/src/ -c shape3d_stack.cpp -o shape3d_stack.o
shape3d_stack.cpp: In constructor ‘shape3d_stack::shape3d_stack(unsigned int)’:
shape3d_stack.cpp:21: error: cannot allocate an object of abstract type ‘shape3d’
shape3d.hpp:10: note: because the following virtual functions are pure within ‘shape3d’:
shape3d.hpp:16: note: virtual double shape3d::area() const
shape3d.hpp:17: note: virtual double shape3d::volume() const
Eu acho que esse deve ser algum tipo de erro de design realmente feio causado por mim mesmo. Então, como seria a maneira correta de usar todos os tipos de objetos derivados de "Shape3D" com minha pilha?
Solução
Você não pode criar objetos a partir de classes abstratas.
Você provavelmente vai querer criar uma variedade de ponteiros para a classe abstrata, que é permitida, e preenchê -los com instâncias derivadas:
// declaration somewhere:
shape3d** array_;
// initalization later:
array_ = new shape3d*[size];
// fill later, triangle is derived from shape3d:
array_[0] = new triangle;
Outras dicas
A linha
array_ = new shape3d[size];
aloca uma variedade de objetos Shape3D. Não cubos, nem esferas, apenas shape3d antigo. Mas não é possível criar um objeto Shape3D, pois é abstrato.
Em geral, para usar o polimorfismo e as funções virtuais, você precisa usar indiretas: ponteiros e/ou referências, não objetos literais. Um Shape3d* pode apontar para um cubo ou para uma esfera, mas um Shape3D é sempre um Shape3D, não uma subclasse do Shape3D.
Desde shape3d
é uma classe base abstrata, você provavelmente quer que sua pilha armazenasse ponteiros para shape3d
, em vez de objetos reais.
Você não pode criar uma nova matriz da classe abstrata. O que você pode fazer é declará -lo como uma variedade de ponteiros e, mais tarde, quando você sabe que tipo de forma é que pode alocar os objetos da classe derivada de sua escolha.
Em vez de uma pilha de objetos, você precisa criar uma pilha de indicadores para objetos.