18.11 Printing inherited classes using operator<<
https://www.learncpp.com/cpp-tutorial/printing-inherited-classes-using-operator/
virtualfunctionを使用した以下のプログラムを見てみましょう
std::coutと結びつけたいのですが、現在の形式ではきれいに使えません.
理想的には、以下のように簡潔明瞭に書く
オペレータ<<通常の方法で再ロードしましょう
Base
Derived
BaseRefに出力し、Derived objectに移動します.
Base
これは私たちが望んでいる結果ではありません.
では、operatoro<<を仮想化できますか?
簡単に言えば、あり得ない.
第一に、member関数のみが仮想化できる
第二に,できれば演算子の定義から,パラメータはそれぞれBase,Derivedである.
では、どうすればいいのでしょうか.
答えは意外と簡単
メンバー関数の利用
従って、出力は以下のようになる
Base
Derived
Derived
virtualfunctionを使用した以下のプログラムを見てみましょう
#include <iostream>
class Base
{
public:
virtual void print() const { std::cout << "Base"; }
};
class Derived : public Base
{
public:
void print() const override { std::cout << "Derived"; }
};
int main()
{
Derived d{};
Base& b{ d };
b.print(); // will call Derived::print()
return 0;
}
b.print呼び出しDerived::print()について説明します.std::coutと結びつけたいのですが、現在の形式ではきれいに使えません.
#include <iostream>
int main()
{
Derived d{};
Base& b{ d };
std::cout << "b is a ";
b.print(); // messy, we have to break our print statement to call this function
std::cout << '\n';
return 0;
}
b.print()はstd::coutが存在します.上のように書くべきです.理想的には、以下のように簡潔明瞭に書く
std::cout << "b is a " << b << '\n'; // much better
The challenges with operator<<
オペレータ<<通常の方法で再ロードしましょう
#include <iostream>
class Base
{
public:
virtual void print() const { std::cout << "Base"; }
friend std::ostream& operator<<(std::ostream& out, const Base& b)
{
out << "Base";
return out;
}
};
class Derived : public Base
{
public:
void print() const override { std::cout << "Derived"; }
friend std::ostream& operator<<(std::ostream& out, const Derived& d)
{
out << "Derived";
return out;
}
};
int main()
{
Base b{};
std::cout << b << '\n';
Derived d{};
std::cout << d << '\n';
return 0;
}
上のプログラムを実行し、次のように出力します.Base
Derived
BaseRefに出力し、Derived objectに移動します.
int main()
{
Derived d{};
Base& bref{ d };
std::cout << bref << '\n';
return 0;
}
このとき出力は次のようになります.Base
これは私たちが望んでいる結果ではありません.
Can we make Operator << virtual?
では、operatoro<<を仮想化できますか?
簡単に言えば、あり得ない.
第一に、member関数のみが仮想化できる
第二に,できれば演算子の定義から,パラメータはそれぞれBase,Derivedである.
では、どうすればいいのでしょうか.
The solution
答えは意外と簡単
メンバー関数の利用
#include <iostream>
class Base
{
public:
// Here's our overloaded operator<<
friend std::ostream& operator<<(std::ostream& out, const Base& b)
{
// Delegate printing responsibility for printing to member function print()
return b.print(out);
}
// We'll rely on member function print() to do the actual printing
// Because print is a normal member function, it can be virtualized
virtual std::ostream& print(std::ostream& out) const
{
out << "Base";
return out;
}
};
class Derived : public Base
{
public:
// Here's our override print function to handle the Derived case
std::ostream& print(std::ostream& out) const override
{
out << "Derived";
return out;
}
};
int main()
{
Base b{};
std::cout << b << '\n';
Derived d{};
std::cout << d << '\n'; // note that this works even with no operator<< that explicitly handles Derived objects
Base& bref{ d };
std::cout << bref << '\n';
return 0;
}
printというvirtualmember関数を使用してoperator<<で実行すればよい従って、出力は以下のようになる
Base
Derived
Derived
Reference
この問題について(18.11 Printing inherited classes using operator<<), 我々は、より多くの情報をここで見つけました https://velog.io/@ikmy0ung/18.11-Printing-inherited-classes-using-operatorテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol