std::basic_ios
にはパブリックコンストラクタがあります :
explicit basic_ios (std::basic_streambuf<CharT,Traits>* sb);
IMO、クラスがパブリックコンストラクターを持つ唯一の理由は、プログラムでそのクラスのスタンドアロンインスタンスを使用することです。 (basic_ios
の場合にそうであるように)他のクラスがその子孫を持つためだけにクラスが存在する場合、クラスのすべてのコンストラクターはprotected
である必要があります。 std::ios_base
のコンストラクタはすべて保護されています。しかし、何らかの理由で、標準の設計者はこれをbasic_ios
の1つのコンストラクターに公開しました。
basic_ios
は、いくつかのストリームタイプの基本クラスとして使用されます。また、少なくともbasic_istream
またはbasic_ostream
でなかった使用例を想定することはできません。ありますか?
私が気づかなかったのは、std::basic_istream
、std::basic_ostream
、およびstd::basic_iostream
にもパブリックコンストラクターがあることです(それぞれがstd::basic_streambuf*
を使用します)。
これにより、多型のジェネリックプログラミングアナログを、pimplイディオムと同じように使用できます。
つまり、この方法で、特殊なstreambuf型を作成し、それをbasic_
[io] stream
で使用できます。特殊なストリームクラスを作成する必要はありません。 (機能は制限されています。同じストリームに新しいバッファーを割り当てることはできません。また、バッファーの有効期間と所有権を外部から追跡する必要があります)。
専用のbasic_
[io] fstream
およびbasic_
[io] stringstream
にはそれぞれ、関連するバッファタイプの完全なインスタンスが含まれています。つまり、特殊なストリームタイプのインスタンスは、その内部バッファでのみ機能し、別のタイプではなく、同じタイプのインスタンスでも機能します。生のbasic_
[io] stream
を使用することは、これに対する(不格好な)回避策です。
template<class C, class TR>
class snazzy_filebuf: public std::basic_streambuf<C, TR>
{
protected:
typename TR::int_type overflow(TR::int_type) override;
typename TR::int_type underflow(TR::int_type) override;
typename TR::int_type pbackfail(TR::int_type) override;
public:
snazzy_filebuf();
};
.....
snazzy_filebuf<char> buf;
std::basic_ostream<char> o_s(&buf);
o_s << "Hello, world\n";