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

即使对象是有导游的游览,它也总是执行游览中指定的内容。

你能帮忙吗?

4

2 回答 2

3

你几乎在做正确的事,但并不完全正确。让我们先来看输出案例——输入案例的工作原理是一样的。

首先,您应该声明一个

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
}

之后,您可以为 s 声明一个自由(即非成员)operator<<重载Tour,它会调用您的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*指针,所以您应该为您的基类定义一个虚拟析构函数。如果您不这样做,编译器将不会知道在GuidedTour您调用. 事实上,如果您的类包含任何其他虚函数,则将析构函数设为虚函数通常是一种很好的做法,只是为了以后避免潜在的问题。deleteTour*

另外,请不要放入using namespace std;头文件:-)

于 2013-10-15T10:16:52.120 回答
0

如果我理解正确,您的向量中有指针。所以你应该使用关键字virtual。并阅读 C++ 中的虚拟方法。

于 2013-10-15T08:56:19.763 回答