15

std::basic_ios有一个公共构造函数

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

IMO,类具有公共构造函数的唯一原因是在程序中使用该类的独立实例。如果一个类的存在只是为了让其他类从它派生出来(似乎是这种情况basic_ios),那么该类的所有构造函数都应该是protected. 的构造函数std::ios_base都受到保护。但是,出于某种原因,该标准的设计者basic_ios公开了这一构造函数。

basic_ios被用作几种流类型的基类,我无法想象一个用例,你会有一个至少不是 abasic_istreambasic_ostream. 有吗?

4

2 回答 2

1

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

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

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

    public:
    A(void*);
    };

 A a(10);

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

于 2019-11-26T21:56:43.610 回答
0

我没有注意到的是std::basic_istreamstd::basic_ostream并且std::basic_iostream还有公共构造函数(每个都需要一个std::basic_streambuf*)。

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

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

专门的basic_[io]fstreambasic_[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";
于 2020-02-10T19:04:30.227 回答