Crear puntero a clase abstracta y problema usando vector

Iniciado por cNoob, 7 Enero 2018, 19:24 PM

0 Miembros y 1 Visitante están viendo este tema.

cNoob

Hola!
Estoy haciendo un programa que consiste en una biblioteca que puede almacenar una serie de items, que son guardados en un vector (ficha). La clase CFicha es abstracta y es la clase base para todas las demás (libros, revistas, etc...). Aquí les dejo la clase CBiblioteca:
Código (cpp) [Seleccionar]
class CBiblioteca
{
   vector<CFicha *> ficha;
   
   public:
       //basico
       CBiblioteca();
       CBiblioteca(const CBiblioteca&);
       ~CBiblioteca();
       CBiblioteca operator=(const CBiblioteca&);
       CFicha* operator[](unsigned);

       //funciones
       void AnyadirFicha(CFicha&);
       int BuscarFicha(const string) const;
       //eliminar siguiente ?
       bool EliminarFicha(unsigned);
       bool MostrarFicha(unsigned);
       bool MostrarBiblioteca(void);
};

Mi problema se da en el método 'operator=' y 'AnyadirFicha()', los cuales son definidos así:
Código (cpp) [Seleccionar]
CBiblioteca CBiblioteca::operator=(const CBiblioteca& bib)
{
   //primero vaciamos la matriz
   for(int i = 0; i < ficha.size(); i++)
       delete ficha[i];

   ficha.clear();

   //ahora copiamos los elementos
   for(int i = 0; i < bib.ficha.size(); i++)
       ficha.push_back(new CFicha(*(bib.ficha[i])));

   return *this;
}

y
Código (cpp) [Seleccionar]
void CBiblioteca::AnyadirFicha(CFicha& ficha)
{
   ficha.push_back(new CFicha(ficha));
}

ambas me dan los mismos dos errores:
'class CFicha' has no member named 'push_back'
invalid new-expression of abstract class type 'CFicha'

pero no entiendo por que interpreta que push_back es un método de CFicha y no de la clase vector, así como mi otra duda de si se puede crear un objeto abstracto con el operador new.
Wannabe programador autodidacta de c++
"Usain Bolt comenzó gateando."

ivancea96

Código (cpp) [Seleccionar]
void CBiblioteca::AnyadirFicha(CFicha& ficha)
{
    ficha.push_back(new CFicha(ficha));
}


Fíjate que llamaste al parámetro igual que al miembro vector. Así que cuando escribes ficha, interpreta que es el parámetro. Tendrías que poner "this->ficha" para acceder, o mejor, cambiar los nombres. Por este motivo entre otros, a los campos privados de una clase, se les suele poner un '_' al inicio ("_ficha"). Sefún nomenclatura.
En cualquier caso, cambia algún nombre.

Luego, no, no puedes crear una clase abstracta. la razón de las clases abstractas es ser heredadas y que se implementen sus métodos. No tiene lógica crear un objeto de una clase abstracta, porque tendrá métodos sin definir.

cNoob

Awww dios, que error más tonto el primero  :-X
Respecto al segundo, mi intención es crear un puntero de una clase base para almacenar en el un objeto de una clase derivada de esta. En algún libro de POO he visto que hacen eso y me suena que era algo por el estilo de lo que estoy haciendo yo .-.
Wannabe programador autodidacta de c++
"Usain Bolt comenzó gateando."

ivancea96

Sin duda puedes tener punteros a clases abstractas, nada de eso es incorrecto. lo que no puedes es crear un objeto de una clase abstracta. Tienes que crear un objeto de una de sus clases derivadas.

cNoob

y al hacer
Código (cpp) [Seleccionar]
ficha[i] = new CFicha
no estoy usando punteros solamente?
Wannabe programador autodidacta de c++
"Usain Bolt comenzó gateando."

ivancea96

Pero no puedes instanciar una clase abstracta, sea puntero o no. Una clase abstracta no se puede instanciar por sí sola, tiene que heredarse de ella.

ThunderCls

Como te dicen anteriormente es un error de concepto querer instanciar una clase abstracta. Te recomiendo profundizar en temas de polimorfismo y clases abstractas.

Correcto:
TAbstract *abs = new TDerived();
abs->método(); // polimorfismo

Incorrecto:
TAbstract *abs = new TAbstract();
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/