为什么`std :: basic_ios`具有公共构造函数?

时间:2019-11-26 16:10:45

标签: c++ stream language-lawyer design-rationale

std::basic_ios has a public constructor

explicit basic_ios (std::basic_streambuf<CharT,Traits>* sb);

IMO,类具有公共构造函数的唯一原因是在程序中使用该类的独立实例。如果仅存在一个类以使其他类从其派生(如basic_ios的情况),则该类的所有构造函数都应为protectedstd::ios_base的构造函数均受保护。但是,由于某种原因,该标准的设计者公开了basic_ios的这一构造函数。

basic_ios用作几种流类型的基类,并且我无法设想用例中至少有一个basic_istream或{{1 }}。有一个吗?

2 个答案:

答案 0 :(得分:1)

类具有公共构造函数的另一个原因是可以使用此构造函数签名来构造派生对象:

struct B{
  B(int);
  protected:
  ~B();
  };

 struct A:B{
    private://no effect.
    using B::B;

    public:
    A(void*);
    };

 A a(10);

构造函数必须在基类中是公共的,因为使用基本构造函数的using声明不会更改继承的构造函数的可访问性。

答案 1 :(得分:0)

我没注意到的是std::basic_istreamstd::basic_ostreamstd::basic_iostream也有公共构造函数(每个都有一个std::basic_streambuf*)。

这允许多态性的通用编程类似物,与pimpl习惯用法相同。

也就是说,通过这种方式,您可以创建特殊的streambuf类型,并在basic_ [io] stream中使用它,而不必创建特殊的流类。 (功能是有限的:您不能将新缓冲区分配给相同的流,并且必须从外部跟踪缓冲区的生存期和所有权)。

专用的basic_ io fstreambasic_ io stringstream各自包含关联缓冲区类型的完整实例。这意味着专用流类型的实例将仅使用其内部缓冲区,而不能使用另一个实例,甚至不能使用相同类型的实例。使用原始的basic_ 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";