web-dev-qa-db-ja.com

`std :: basic_ios`にパブリックコンストラクタがあるのはなぜですか?

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でなかった使用例を想定することはできません。ありますか?

15
Spencer

私が気づかなかったのは、std::basic_istreamstd::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";
0
Spencer