子类中的重载运算符

时间:2013-10-15 08:51:30

标签: c++ operator-overloading

旅行和导游。导游延伸了旅游课程。我正在超载<<和>>旅行团的操作员。

我的旅游课程看起来像

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

即使对象是导游,它始终会执行巡视中指定的内容。

你能帮忙吗?

2 个答案:

答案 0 :(得分: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
}

之后,您可以为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上调用delete时,编译器将不会知道可能需要销毁Tour*类的所有成员。实际上,如果您的类包含任何其他虚函数,那么通常很好的做法是将析构函数设置为虚拟,以便以后节省潜在的问题。

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

答案 1 :(得分:0)

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