2013-10-15 72 views
1

旅遊和導遊。導遊將延續旅遊課程。我在巡迴課上超載< <和>>操作員。子類中的重載操作符

我的導遊班的樣子

#include <iostream> 
#include <vector> 
#include "Customer.h" 

using namespace std; 

class Tour { 

protected: 
    string id; 
    string description; 
    double fee; 
    vector<string> customerList; 

public: 
    Tour(); 
    Tour(string idVal, string descriptionVal, double feeVal); 
    string getId(); 
    string getDescription(); 
    double getFee(); 
    double getTotalForTour(); 
    virtual void addCustomer(string cust); 
    vector<string> getCustomers(); 
    virtual void display(); 

    friend ostream& operator<< (ostream &out, Tour &cust); 
    friend istream& operator>> (istream &in, Tour &cust); 
}; 

那麼我的導遊是這樣的,

#include <iostream> 
#include "Tour.h" 
#include "SimpleDate.h" 

using namespace std; 

class GuidedTour : public Tour { 

private: 
    SimpleDate* date; 
    string guideName; 
    int maxNumTourists; 

public: 
    GuidedTour(); 
    GuidedTour(string idVal, string descriptionVal, double feeVal, SimpleDate* dateVal, string guideNameVal, int maxNumTouristsVal); 
    virtual void addCustomer(string cust); 
    SimpleDate* getDate(); 
    void display(); 

    friend ostream& operator<< (ostream &out, GuidedTour &cust); 
    friend istream& operator>> (istream &in, GuidedTour &cust); 
}; 

我想不同的重載這些運營商的子類做別的事情。

我有一個矢量包含旅遊和導遊。

當我遍歷向量,並執行以下,

for (unsigned int i = 0; i < tourListVector.size(); i++) { 

    cout << *tourListVector[i]; 
} 

它總是做什麼在旅遊指定無論即使對象是導遊。

你能幫忙嗎?

+1

[這](http://stackoverflow.com/q/4571611/812912)可以幫助 –

+2

虛擬'閱讀(STD: :stream&)'和'write(std :: ostream&)'從友誼的基類運算符中調用將消除派生類中運算符的重寫需要。派生類重寫'read'和'write'(甚至可以根據需要直接調用基類作爲派生函數的一部分)。 – WhozCraig

+0

你能解釋這一點嗎?對不起,我很新C++ –

回答

2

你幾乎做對了,但不完全。讓我們先看看輸出案例 - 輸入案例的工作原理是一樣的。

首先,你應該在你的基類聲明

virtual void write(std::ostream&) const; 

成員函數。實現可能是這樣的:

void Tour::write(std::ostream& os) const 
{ 
    os << "ID: " << id << std::endl; 
    os << "Description: " << description << std::endl; 
    // etc 
} 

我以爲是何許代碼,你目前在你的operator<<(ostream&, Tour&)。然後,你需要在你的派生類中重載這一點 - 也許像

void GuidedTour::write(std::ostream& os) const 
{ 
    Tour::write(os); // Write out base Tour info first 
    os << "Guide Name: " << guideName << std::endl; 
    // etc 
} 

之後,你可以聲明一個免費的(即非會員)operator<<過載Tour s,這要求你的write()成員函數,像

std::ostream& operator<<(std::ostream& os, const Tour& tour) 
{ 
    tour.write(os); 
    return os; 
} 

例如。

說明:忘記您目前的operator<<是朋友;它在這種情況下沒有軸承。相反,想象你有一個名爲

void do_something(Tour& t); // (a) 
void do_something(GuidedTour& gt); // (b) 

兩個重載的非成員函數。由於您的tourListVector包含(我認爲)Tour*指針,如果通過矢量是循環和每個元素調用do_something(),編譯器將只能夠匹配上面的功能(a)。這是因爲它無法知道某些Tour*指針可能對於給定的程序運行,實際上指向GuidedTour實例。爲了做這樣的運行時調度,你需要使用虛函數。

除了:(我知道這是示例代碼,但如果你是新的C++那麼它值得指出的,以防萬一你不知道:-))

因爲你使用Tour*指針,你應該爲你的基類定義一個虛擬析構函數。如果你不這樣做,編譯器不會知道在Tour*上調用delete時,它可能需要破壞GuidedTour類的所有成員。實際上,如果您的類包含任何其他虛擬函數,那麼使您的析構函數變爲虛擬是一種很好的做法,以便稍後節省潛在的問題。

而且,請不要把using namespace std;在頭文件:-)

0

如果我理解正確,你有向量中的指針。所以你應該使用關鍵字虛擬。並閱讀關於C++中的虛擬方法。

+0

如果我使用虛擬我得到錯誤 Tour.h:36:錯誤:虛擬功能不能成爲朋友 –

+1

@Archie:你重寫一個'print'虛擬函數並讓'operator <<'調用它。 –