如何使用多态插入运算符?

How can I use the insertion operator with polymophism

本文关键字:运算符 插入 多态 何使用      更新时间:2023-10-16

我想实现一个复合模式,可以使用std::cout

打印内容

打印时,使用基类插入操作符(operator<<)而不是最派生的类型。如何使用派生最多的类型操作符?

的例子:

#include <iostream>
#include <memory>
using namespace std;
class Base {
    int i;
public:
    Base(int _i) : i(_i) {}
    virtual ~Base() {}
    friend inline ostream& operator<<(ostream& os, Base& value) { return os << "i: " <<  value.i; }
    friend inline ostream& operator<<(ostream& os, shared_ptr<Base> value) { return os << "i: " <<  value->i; }
};
class Derived : public Base {
    int x;
public:
    Derived(int _x) : Base(2*_x), x(_x) {}
    friend inline ostream& operator<<(ostream& os, Derived& value) { return os << "x: " << value.x; }
    friend inline ostream& operator<<(ostream& os, shared_ptr<Derived> value) { return os << "x: " << value->x; }
};
int main () {
    Base* a = new Base(1);
    Derived* d = new Derived(6);
    Base* b = new Derived(7);
    shared_ptr<Base> ba = make_shared<Base>(3);
    shared_ptr<Derived> de = make_shared<Derived>(4);
    shared_ptr<Base> bd = make_shared<Derived>(5);
    cout << "a is: " << a << endl;
    cout << "*a is: " << *a << endl;
    cout << "d is: " << d << endl;
    cout << "*d is: " << *d << endl;
    cout << "b is: " << b << endl;
    cout << "*b is: " << *b << endl << endl;
    cout << "ba is: " << ba << endl;
    cout << "*ba is: " << *ba << endl;
    cout << "de is: " << de << endl;
    cout << "*de is: " << *de << endl;
    cout << "bd is: " << bd << endl;
    cout << "*bd is: " << *bd << endl;
    delete a;
    delete d;
    delete b;
    return 0;
}

生活代码

This spits out

a is: 0x1fe2bb0
*a is: i: 1
d is: 0x1fe2bd0
*d is: x: 6
b is: 0x1fe2bf0
*b is: i: 14
ba is: i: 3
*ba is: i: 3
de is: x: 4
*de is: x: 4
bd is: i: 10
*bd is: i: 10

但我希望看到*b打印7和bd打印5(即。使用派生类的插入操作符)

好的,在搜索了很多之后,我找到了这个答案。在摇了摇头说了"当然"之后,我总结道:

不要重载插入操作符,因为不能使其为虚函数(它不是成员函数),而是在基类中声明虚函数,并在子类中重写。插入操作符使用以下函数:

class Base {
    ...
    friend inline ostream& operator<<(ostream& os, shared_ptr<Base> value) { return value->display(os, value); }
    virtual ostream& display(ostream& os) { os << "i: " << i << endl; }
};
class Derived : public Base {
    ...
    ostream& display(ostream& os) { os << "x: " << x << endl; }
};

生活代码