簡體   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