Чому `std :: basic_ios` має публічний конструктор?


15

std::basic_iosмає публічний конструктор :

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

IMO, єдиною причиною для класу мати загальнодоступний конструктор - використовувати окремий екземпляр цього класу в програмі. Якщо клас існує лише для того, щоб з нього сходили інші класи (як це здається basic_ios), всі конструктори класу повинні бути protected. Усі конструктори std::ios_baseзахищені. Але чомусь дизайнери стандарту зробили цей конструктор basic_iosзагальнодоступним.

basic_iosвикористовується як базовий клас для декількох типів потоків, і я не можу передбачити випадок використання, коли у вас був би той, який не був принаймні a basic_istreamабо basic_ostream. Чи є такий?

Відповіді:


1

Інша причина, щоб клас мав публічний конструктор - це підпис цього конструктора доступний для побудови похідного об'єкта:

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

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

    public:
    A(void*);
    };

 A a(10);

Конструктор повинен бути відкритим у базовому класі, оскільки використання декларації базового конструктора не змінює доступність спадкового конструктора.


2
Здається, за винятком afaik, basic_iosctor, який приймає a basic_streambuf*, був публічним з тих пір, як ви могли це зробити using B::B;. Я думаю, що у старих реалізаціях просто був проксі-сервер: A(int x) : B(x) {}- який працює добре, навіть якщо Bє ctor protected.
Тед Лінгмо

0

Що я не помітив, це було std::basic_istream, std::basic_ostreamа std::basic_iostreamтакож були громадські конструктори (кожен займає а std::basic_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";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.