继承istream运算符>>

时间:2015-04-21 01:36:11

标签: c++ class inheritance operator-keyword istream

我在课程PhoneNumber中有一个功能:

class PhoneNumber
{
protected:
    int area;
    long number;
public:
    istream& operator>>(istream& is, PhoneNumber &p){
        cout << "Enter area code : ";
        is >> p.area;
        cout << "Enter number telephone number : ";
        is >> p.number;
        return is;
    }
};

和类中的另一个函数如下:

class IntPhoneNumber::public PhoneNumber
{
    int reg;
    public 
    friend istream& operator>>(istream& is, IntPhoneNumber &p);
};

我希望课程IntPhoneNumber继承并使用课程operator>>中的PhoneNumber

2 个答案:

答案 0 :(得分:2)

一种可以很好地扩展的方法是从operator>>委托给PhoneNumber的虚拟成员函数,然后在派生类中提供重载 - 如果他们愿意,可以回调到父类

class PhoneNumber {
protected:
    int area;
    long number;
public:
  friend istream& operator>>(istream& is, PhoneNumber &p);

  virtual void getFromStream(istream& is) {
        cout << "Enter area code : ";
        is >> area;
        cout << "Enter number telephone number : ";
        is >> number;
  }
};

istream& operator>>(istream& is, PhoneNumber &p) {
   p.getFromStream(is);
}

现在你可以像这样重载:

class IntPhoneNumber::public PhoneNumber {
    int reg;
    virtual void getFromStream(istream& is) {
      PhoneNumber.getFromStream(is);
      cout << "Enter reg :";
      is >> reg;
    }
};

答案 1 :(得分:1)

首先,您必须将提取器声明为朋友:

class PhoneNumber
{
protected:
    int area;
    long number;
public: 
    ...
    friend istream& operator>>(istream& is, PhoneNumber &p);
};

然后你在课堂外定义了operator>>

istream& operator>>(istream& is, PhoneNumber &p) 
{
        cout << "Enter area code : ";
        is >> p.area;
        cout << "Enter number telephone number : ";
        is >> p.number;
        return is;

};

现在已经使用了这个结构,如果您不关心区域代码,则可以对派生的operator>>使用相同的IntPhoneNumber

struct IntPhoneNumber:public PhoneNumber
{
protected:
    int reg;
public:
    ...
};

此代码将IntPhoneNumber完全编译和处理PhoneNumber

PhoneNumber n;
cout<< "Request phone number"<<endl; 
cin >> n;  
cout<< "Request phone int number"<<endl; 
IntPhoneNumber ni; 
cin>>ni; 

现在,如果您想覆盖运算符&gt;&gt;对于IntPhoneNumber,但重用已经为PhoneNumber编写的内容,它也不是问题。只需定义另一个朋友并使用强制转换:

class IntPhoneNumber:public PhoneNumber
{
protected:
    int reg;
public:
    ...
    friend istream& operator>>(istream& is, IntPhoneNumber &p);
};

istream& operator>>(istream& is, IntPhoneNumber &p) 
{
    cout << "Enter area code : ";  // do the specific
    is >> p.reg;
    return is >> static_cast<PhoneNumber&>(p);  // and call the general one
};

这里有一个live demo on ideone用于输入和输出。

备注: 可以进行概念验证。但通常对于提取器重载(即operator>>),您不应该在cout上显示:如果相同的提取器将用于从文件中读取数据,则屏幕将被用户的消息淹没并且阅读操作会变慢。这就是为什么我在现场演示中添加了一些if (is==cin)