2011-12-04 66 views
0

我有一個名爲項目基類:ostream的操作符重載 - 繼承

#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 

,我有一個派生類

#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 

源代碼

#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; 
} 

現在我想對代碼進行測試,看看是否運算符重載正常工作:

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 
} 

由於可以從代碼可以理解,一卡保存的整數值距離和枚舉值方向。如果我也包含了這些代碼,那將會是一團糟。我在最後一段代碼test()中評論了我的問題。感謝您的幫助提前。

+1

¤'Item items2 [1]'創建一個'Item'對象的數組。當你在那裏複製一個'Tower'對象時,所有複製的都是'Item'基類子對象。這就是**切片**。該副本是「Item」類型的副本。這些位(在你的情況下爲零位,但不重要)不記得它們是從派生類型的對象中複製的,特別是對於幾乎所有C++實現工作的方式,* vtable指針*在對象中指向'Item'類的虛表。乾杯&hth。, –

回答

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

這裏發生的事情叫做「切片」。既然你不存儲指針,但是實際的對象,這個類的Tower部分只是被切斷了,只有Item部分被壓入了向量。要使用虛函數和多態,需要一個引用或指向基類的指針。

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]; 

或者從升壓智能指針或C++ 11庫

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

印刷,現在顯然需要取消引用指針:

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

}

+0

有趣的是,我不知道。非常感謝@ Xeo – Radix

+0

@氨基酸:如果這個答案解決了你的問題,你應該點擊它旁邊的小勾號。 :) – Xeo