【问题标题】:Inheriting istream operator>>继承 istream 运算符>>
【发布时间】:2015-06-27 23:22:14
【问题描述】:

我在课堂上有一个函数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 类继承并在 PhoneNumber 类中使用 operator&gt;&gt;

【问题讨论】:

  • 请标记语言并修正代码的缩进。
  • 在派生类中创建一个虚拟的get(std::istream&amp;) 方法。为基类创建一个非成员运算符重载插入器并调用p.get(is)。在派生类中,您可以覆盖该函数,以便您拥有不同的插入语义。

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


【解决方案1】:

一种很好的可扩展方式是从operator&gt;&gt; 委托给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;
    }
};

【讨论】:

    【解决方案2】:

    首先你必须将你的提取器声明为朋友:

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

    然后你在类之外定义了operator&gt;&gt;

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

    现在已经有了这个构造,如果你不关心区域代码,你可以使用相同的operator&gt;&gt; 派生的IntPhoneNumber

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

    这段代码将像PhoneNumber一样编译和处理IntPhoneNumber

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

    现在,如果您想为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&gt;&gt;),您不应该在cout 上显示:如果将使用相同的提取器从文件中读取数据,则屏幕将被用户消息和读取操作淹没会放慢速度。这就是为什么我在现场演示中添加了一些if (is==cin)

    【讨论】:

      猜你喜欢
      • 2011-07-08
      • 2023-04-02
      • 1970-01-01
      • 2012-02-28
      • 2011-12-05
      • 2021-12-16
      • 2015-06-13
      • 2015-11-19
      • 1970-01-01
      相关资源
      最近更新 更多