Pregunta

Tengo una clase base llamada Artículo:

#ifndef ITEM_H
#define ITEM_H

#include <ostream>

class Item {
public:
    virtual ~Item() {}
    virtual void print(std::ostream& out) const {}
    friend std::ostream& operator << (std::ostream& out, Item& item){
    item.print(out);
    return out;
    }
};



#endif

y tengo una clase derivada Torre:

#ifndef TOWER_H
#define TOWER_H

#include <iostream>
#include <iostream>
#include <exception>
#include "item.h"
#include "Card.h"

class Tower : public Item {
    unsigned height;
        void print(std::ostream& o) const;
public:
    Tower(const Card& card);
    int demolish(Card& card) const;
    unsigned getHeight() const;
};

#endif

Código fuente para Torre:

#include "tower.h"



Tower::Tower(const Card& card){
    height = card.getDis();
}

void Tower::print(std::ostream& o) const {
    o << height;
}


int Tower::demolish(Card& card) const{
    try {
    if(height != card.getDis()){
            throw std::exception ();
        } else {
            return height;
        }
    } catch (std::exception e){
        cout<< "Card's value not enough to demolish the tower." << endl;
    }
}

unsigned Tower::getHeight() const {
    return height;
}

Ahora estoy tratando de probar el código para ver si la sobrecarga del operador funciona correctamente:

void test() {
    Card card (Card::SOUTH, 3);
    Tower tower(card);

    std::cout << "Printing tower: " << tower << std::endl;  //PRINTS OUT 3 AS EXPECTED

    Card one (Card::NORTH, 2);
    Card two (Card::WEST, 3);

    std::cout << "Expecting to receive an error: " <<endl;
    tower.demolish(one);

    std::cout << "Expecting to have the tower demolished: ";
    std::cout << tower.demolish(two) <<std::endl;

    std::cout << "Height of the tower: " << tower.getHeight() <<std::endl;

    std::vector<Item> items;       //creating an Item vector
    items.push_back(Tower(one));

    Item items2[1];                //creating an array of Items
    items[0]= tower;

    std::cout << "Printing out an Item: ";    
    std::cout << items.back()<<std::endl;   //EXPECTING TO GET 2 BUT IT PRINTS NOTHING, WHY IS THAT?
    std::cout << "OR: " << items2[0]<<std::endl;  //SAME ISSUE HERE, EXPECTING TO GET 3
}

Como se puede entender en el código, una tarjeta tiene un valor entero distancia y un valor de enum dirección. Hubiera sido un desastre si también hubiera incluido ese código. He comentado mis preguntas en la última pieza de código. prueba(). Gracias por su ayuda de antemano.

¿Fue útil?

Solución

std::vector<Item> items;       //creating an Item vector
items.push_back(Tower(one));

Lo que sucede aquí se llama "corte". Como no estás almacenando punteros, sino objetos reales, el Tower parte de la clase es simplemente cortada y solo la Item Parte se empuja en el vector. Para usar funciones virtuales y polimorfismo, necesita una referencia o un puntero a la clase base.

std::vector<Item*> items;       //creating an Item vector
items.push_back(new Tower(one));
// ...
// at the end of main:
for(int i=0; i < items.size(); ++i)
  delete items[i];

O con consejos inteligentes de Boost o una biblioteca C ++ 11

std::vector<shared_ptr<Item>> items;
items.push_back(make_shared<Tower>(one));
// nothing further needs to be done

Para la impresión, ahora obviamente necesitas deselerar el puntero:

std::cout << "Printing out an Item: ";    
std::cout << *items.back()<<std::endl;
std::cout << "OR: " << *items2[0]<<std::endl;

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top