在子类中重载操作符 [英] Overload operator in subclass

查看:237
本文介绍了在子类中重载操作符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

旅游和导游。导游延长了旅游类。我超载<<

 <$ c 

$ c> #include< iostream>
#include< vector>
#includeCustomer.h

使用namespace std;

class Tour {

protected:
string id;
string description;
双费;
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&运算符<< (ostream& out,Tour& cust);
friend istream& operator>> (istream& in,Tour& cust);
};

那么我的导览就像这样,

  #include< iostream> 
#includeTour.h
#includeSimpleDate.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&运算符<< (ostream& out,GuidedTour& cust);
friend istream& operator>> (istream& in,GuidedTour& cust);
};

我想在子类上重载这些操作符,以做别的事。



我有一个矢量,包含旅游和导游。



当我循环遍历向量并执行以下操作时,

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

cout< * tourListVector [i];
}

它总是在旅游中指定,即使对象是导游。



您能帮忙吗?

解决方案

正确的事情,但不完全。让我们先来看输出案例 - 输入案例的工作原理是一样的。



首先,你应该声明一个

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

成员函数。实现可能类似:

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

目前在您的运算符<<(ostream& amp; Tour&)。然后你需要在你的派生类重载这个 - 可能是像

  void GuidedTour :: write(std :: ostream& ; os)const 
{
Tour :: write(os); //写出基础旅行信息第一
os<< 指南名称:< guideName<< std :: endl;
// etc
}

之后,您可以声明一个免费即非成员)运算符< <$ / code>重载 Tour s,它调用您的 ()成员函数,如

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



说明:忘记您当前的运算符<< 是朋友的事实;在这种情况下它没有轴承。相反,假设你有两个重载的非成员函数

  void do_something(Tour& //(a)
void do_something(GuidedTour& gt);由于您的 tourListVector 包含(我假设) Tour * 指针,如果你要循环通过向量,并调用 do_something()元素,编译器将只能匹配上面的函数(a)。这是因为它没有办法知道一些 Tour * 指针可能,对于给定的程序运行,实际上指向 GuidedTour 实例。为了做这样的运行时调度,你需要使用虚函数。



Aside :(我知道这是示例代码,但是如果你是新来的C ++那么值得指出,以防你不知道:-))



因为你使用 Tour * 指针,你应该为你的基类定义一个虚拟析构函数。如果没有,编译器不会知道当你调用 delete 时,它可能需要破坏 GuidedTour code>在 Tour * 上。事实上,如果您的类包含任何其他虚拟函数,只是为了节省潜在的问题,通常是最好的做法是使您的析构函数成为虚拟函数。



在头文件中使用命名空间std; : - )


tour and guided tour. Guided tour extends the tour class. I'm overloading << and >> operators in the tour class.

My tour class looks like

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

then my guided tour looks like this,

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

I want to overload these operators differently on the subclass to do something else.

I have a Vector that contains tours and guided tours.

When i loop through the vector and do following,

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

    cout << *tourListVector[i];
}

It always does what's specified in tour regardless even if the object is a guided tour.

Can you please help?

解决方案

You're almost doing the right thing, but not quite. Let's take the output case first -- the input case works just the same.

First, you should declare a

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

member function in your base class. The implementation might be something like:

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

which I assume is the sort of code you have currently in your operator<<(ostream&, Tour&). Then you need to overload this in your derived class -- perhaps with something like

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

After that, you can declare a free (i.e. non-member) operator<< overload for Tours, which calls your write() member function, like

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

for example.

Explanation: Forget the fact that your current operator<< is a friend; it has no bearing in this case. Instead, imagine you have two overloaded non-member functions called

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

Since your tourListVector contains (I assume) Tour* pointers, if you were to loop through the vector and call do_something() on each element, the compiler would only be able to match function (a) above. That's because it has no way of knowing that some of the Tour* pointers might, for a given run of your programme, actually point to GuidedTour instances. In order to do run-time dispatching like this, you need to use virtual functions.

Aside: (I know this is example code, but if you're new to C++ then it's worth pointing out just in case you weren't aware :-) )

Because you're using Tour* pointers, you should define a virtual destructor for your base class. If you don't, the compiler won't know that it might need to destruct all the members of the GuidedTour class when you call delete on a Tour*. In fact, it's generally good practice to make your destructor virtual if your class includes any other virtual functions, just to save potential problems later.

Also, please don't put using namespace std; in a header file :-)

这篇关于在子类中重载操作符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆