Tại sao `std :: basic_ios` có một hàm tạo công khai?


15

std::basic_ioscó một nhà xây dựng công cộng :

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

IMO, lý do duy nhất để một lớp có một hàm tạo công khai là sử dụng một thể hiện độc lập của lớp đó trong một chương trình. Nếu một lớp chỉ tồn tại để có các lớp khác xuất phát từ nó (dường như là trường hợp basic_ios), thì tất cả các hàm tạo của lớp sẽ là protected. Các nhà xây dựng của std::ios_basetất cả được bảo vệ. Nhưng, vì một số lý do, các nhà thiết kế của tiêu chuẩn đã tạo ra một công trình xây dựng này basic_ios.

basic_iosđược sử dụng làm lớp cơ sở cho một số loại luồng và tôi không thể hình dung được trường hợp sử dụng mà bạn có ít nhất một basic_istreamhoặc basic_ostream. Có một cái không?

Câu trả lời:


1

Lý do khác để một lớp có một hàm tạo công khai là có sẵn chữ ký hàm tạo này để xây dựng một đối tượng dẫn xuất:

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

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

    public:
    A(void*);
    };

 A a(10);

Hàm tạo phải được công khai trong lớp cơ sở vì việc sử dụng khai báo của hàm tạo cơ sở không thay đổi khả năng truy cập của hàm tạo được kế thừa.


2
Có vẻ như cộng hưởng, ngoại trừ afaik, basic_iosctor lấy một basic_streambuf*đã được công khai kể từ trước khi bạn có thể làm using B::B;. Tôi hy vọng rằng các triển khai cũ chỉ có một ctor proxy: A(int x) : B(x) {}- hoạt động tốt ngay cả khi Bctor là protected.
Ted Lyngmo

0

Điều tôi không nhận thấy là std::basic_istream, std::basic_ostreamstd::basic_iostreamcũng có các nhà xây dựng công cộng (mỗi người mất một std::basic_streambuf*).

Điều này cho phép một sự tương tự lập trình chung của đa hình, trong cùng một mạch với thành ngữ pimpl.

Đó là, theo cách này bạn có thể tạo một loại streambuf chuyên dụng và sử dụng nó trong basic_[io] streammà không phải tạo các lớp stream chuyên biệt. (Chức năng bị giới hạn: Bạn không thể chỉ định một bộ đệm mới cho cùng một luồng và bạn phải theo dõi bên ngoài về thời gian và quyền sở hữu của bộ đệm).

Mỗi basic_[io] fstreambasic_[io] chuyên biệt stringstreamchứa một thể hiện đầy đủ của loại bộ đệm liên quan. Điều này có nghĩa là một thể hiện của một loại luồng chuyên dụng sẽ chỉ hoạt động với bộ đệm bên trong của nó và không phải là một loại khác, thậm chí không phải là một loại cùng loại. Sử dụng một basic_[io] thô streamlà một cách giải quyết (vụng về) cho việc này.

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";
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.