重载输入 重载输入派生类中的基类

Overloading input the base class inside overloading input derived class

本文关键字:重载 输入 基类 派生      更新时间:2023-10-16

我想在类Derived重用Base类中的重载输入函数。

class Base
{
private:
    int m_value;
public:
    Base(int value)
        : m_value(value)
    {
    }
    friend std::istream& operator>> (std::istream &in,Base &b)
    {
        in>>b.m_value;
        return in;
    }
};
class Derived : public Base
{
    std::string id;
public:
    Derived(int value,std::string id)
        : Base(value),id(id)
    {
    }
    friend std::istream& operator>> (std::istream &in,Derived &d)
    {
        in>>static_cast<Base>(d);//not work
        in>>d.id;
        return in;
    }
};

当我编写in>>static_cast<Base>(d)时,我的代码有什么问题?

为了得到dBase部分,你需要投射到Base&
通过强制转换获得的是一个临时Base对象,不能作为非常量引用参数传递。

请注意,此演员表仍然不会使一切按预期工作——例如,

Derived d;
Base &b = d;
std::cin >> b;

将使用Base&重载,因为重载基于b的静态类型。

重载层次结构>>(和<<(的常用方法是只有一个重载,它只委托给虚拟成员函数。
然后,可以重写派生类中的成员函数,并让动态调度负责选择适当的函数。

struct Base
{
    virtual void read(std::istream& is) { ... }
};
std::istream& operator>> (std::istream &in, Base &b)
{
    b.read(in);
    return in;
}
struct Derived: Base
{
    void read(std::istream& is) override { Base::read(is); ... }
};

当你这样做时

static_cast<Base>(d);

你会得到一个Base prvalue,它的基本部分是d。 你不能把它传递给

friend std::istream& operator>> (std::istream &in,Base &b)

虽然因为它需要一个左值。 您需要做的是获取对d Base部分的引用,而不是像

in >> static_cast<Base&>(d);