Перегрузка ввода базового класса внутри перегрузки ввода производного класса - PullRequest
1 голос
/ 31 мая 2019

Я хочу использовать перегрузочные функции ввода из Base класса внутри Derived класса.

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)?

Ответы [ 2 ]

2 голосов
/ 31 мая 2019

Чтобы получить Base часть d, вам необходимо привести к 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); ... }
};
1 голос
/ 31 мая 2019

Когда вы делаете

static_cast<Base>(d);

, вы получаете Base prvalue, базовая часть которого d.Вы не можете передать это

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

, так как для этого требуется lvalue.То, что вам нужно сделать, это получить ссылку на Base часть d вместо этого, например

in >> static_cast<Base&>(d);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...