繁体   English   中英

多态性不适用于指针、operator<< 重载、继承、C++

[英]Polymorphism does not work with pointers, operator<< overload, inheritance, C++

我的代码有问题。 我有两个类, AB ,并且B继承了A 我还在两个类中都重载了运算符<<

一切正常,我没有编译器错误,但似乎有些问题。 据我了解多态性,当我在使用new创建子类时使用指向基类的指针时,调用方法应该匹配子类,而不是基类。

对于下面的代码,

#include <iostream>
using namespace std;

class A
{
    protected:
        int a;

    public:

    A(int aa) : a(aa) {};

    virtual void show(ostream& o) const
    {
        o << "a  = " << a << "\n";
    }
};

ostream& operator << (ostream& os, const A &o)
{
    o.show(os);
    return os;
}

class B : public A
{
    private:
        int b;
    public:
        B(int bb, int aa) : A(aa), b(bb){}
        int getb() const {return b;}
};

ostream & operator << ( ostream & os, const B & o)
{
    os << static_cast <const A &>(o);
    os << "\n";
    os << "b = " << o.getb() << "\n";
    return os;
}

int main()
{
    A *o1 = new B(2,3);
    cout << *o1;

    cout << "---------------------\n";

    B *o2 = new B(2,3);
    cout << *o2;

    return 0;
}

在主要:

A *o1 = new B(2,3);
cout << *o1;

显示a = 3 ,而不是显示a = 3 b = 2 (调用应该匹配子类,而不是基类)。 问题是,我需要在每个子类中实现<<>>运算符,但我认为它们的行为不应该。

程序的输出:

在此处输入图片说明

即使使用重新实现的show方法修改后的代码也显示错误的结果,但此时根本不显示a

#include <iostream>
using namespace std;

class A
{
protected:
    int a;

public:

    A(int aa) : a(aa) {};

    virtual void show(ostream& o) const
    {
        o << "a  = " << a << "\n";
    }
};

ostream& operator << (ostream& os, const A &o)
{
    o.show(os);
    return os;
}

class B : public A
{
private:
    int b;
public:
    B(int bb, int aa) : A(aa), b(bb) {}
    int getb() const
    {
        return b;
    }

    void show(ostream& o) const
    {
        o << "b  = " << b << "\n";
    }
};

ostream & operator << ( ostream & os, const B & o)
{
    os << static_cast <const A &>(o);
    o.show(os);
    return os;
}

int main()
{
    A *o1 = new B(2,3);
    cout << *o1;

    cout << "---------------------\n";

    B *o2 = new B(2,3);
    cout << *o2;

    return 0;
}

在此处输入图片说明

你必须在派生类 B 中实现虚函数show

class B: public A
{
     public:
         // some code here
         virtual void show(ostream& o) const
        {
            o << "b  = " << b << "\n";
        } 
};

当我在使用 new 创建子类时使用指向基类的指针时,调用方法应该匹配子类,而不是基类

当您调用成员函数(在某些其他语言中为“方法”)时,它operator<< ,但operator<<不是成员函数——它是一个重载的自由函数。
选择重载时,仅使用编译时已知的类型。

由于o1A**o1A& ,因此选择了A&的重载。

你这样做有点“倒退”; 对于调用虚拟show的基类,您只需要一个operator<< ,然后在派生类中覆盖show

像这样:

class A
{
    // ...
    virtual void show(ostream& o) const
    {
        o << "a  = " << a << "\n";
    }
};

ostream& operator << (ostream& os, const A &o)
{
    o.show(os);
    return os;
}

class B : public A
{
    // ...
    void show(ostream& o) const override
    {
        A::show(o); // Do the "A part".
        o << "b  = " << b << "\n";
    }
};

operator>>遵循相同的模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM