0

2つのクラスがあります。基本クラスは「Port」で、派生クラスは「VintagePort」です。私の知る限り、派生クラスのオブジェクトへの基本クラスの参照またはポインターを使用すると、参照またはポインターではなく、オブジェクトへの正しいメソッドが自動的に検出されます(メソッドが仮想の場合)。

私の状況では、両方のクラスにフレンド関数「operator<<」があることがわかります。しかし、基本クラスにポインターを使用している場合は、基本クラスからのみ関数を呼び出すように見えます。「cout<<VintagePort」を使用すれば問題なく動作します。私の質問:それは正しく機能していますか、それともコードで何かを修正する必要がありますか?

std::ostream& operator<<(std::ostream& os, const Port& p)
{
os << p.brand << ", " << p.style << ", " << p.bottles << endl;
return os;
}

std::ostream& operator<<(std::ostream& os, const VintagePort& vp)
{
os << (const Port &) vp;
cout << ", " << vp.nickname << ", " << vp.year << endl;
return os;
}




VintagePort vp1;
VintagePort vp2("Gallo", "lekko brazowy", 50, "Blaze", 1990);
VintagePort vp3(vp2);

Port* arr[3];
arr[0] = &vp1;
arr[1] = &vp2;
arr[2] = &vp3;

for (int i = 0; i < 3; i++)
{
    cout << ">>>>> " << i+1 << " <<<<<" << endl;
    cout << *arr[i];   // call for base class instead derived class
    arr[i]->Show();    
}
4

2 に答える 2

5

コンパイラは、ポインタが実際に継承されたクラスを指しているわけではありません。これを解決する1つの方法は、出力用に基本クラスに仮想関数を設定し、基本クラスを継承するクラスで仮想関数をオーバーライドすることです。次に、出力演算子でこの仮想メソッドを呼び出します。

于 2012-07-20T11:29:14.473 に答える
0

C ++では、ポリモーフィズムは仮想関数によってのみ実現でき、operator<<1つではありません(最初の引数がであるため、目的に使用することはできませんstd::ostream。この種の動作が必要な場合、簡単なアプローチは、仮想印刷関数を提供することです。階層を作成し、operator<<動的ディスパッチを実行する呼び出しを転送します。

struct base {  // Don't forget virtual destructors
   virtual void print( std::ostream& ) const;
};
struct derived : base {
   virtual void print( std::ostream& ) const;
};
std::ostream& operator<<( std::ostream& o, const base& b ) {
   b.print( o );
   return o;
}
于 2012-07-20T13:51:33.043 に答える