ทำไม `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จะถูกใช้เป็นชั้นฐานประเภทกระแสหลาย ๆ และฉันไม่สามารถมองเห็นกรณีการใช้งานที่คุณต้องการมีหนึ่งที่ไม่ได้เป็นอย่างน้อยหรือ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 การได้รับของประชาชนตั้งแต่ก่อนที่คุณจะทำbasic_streambuf* using B::B;ผมคาดหวังว่าการใช้งานเก่าเพิ่งมี ctor พร็อกซี: A(int x) : B(x) {}- ซึ่งทำงานได้ดีแม้ว่าB's ctor protectedคือ
Ted Lyngmo

0

สิ่งที่ฉันล้มเหลวที่จะแจ้งให้ทราบก็คือว่าstd::basic_istream, std::basic_ostreamและstd::basic_iostreamยังมีการก่อสร้างสาธารณะ (แต่ละยิงstd::basic_streambuf*)

สิ่งนี้ทำให้อะนาล็อกโปรแกรมทั่วไปของ polymorphism ในหลอดเลือดดำเดียวกันกับ pimpl idiom

นั่นคือวิธีนี้คุณสามารถสร้างประเภทสตรีมเฉพาะและใช้มันในbasic_[io] streamโดยไม่ต้องสร้างคลาสสตรีมแบบพิเศษ (ฟังก์ชันการทำงานมี จำกัด : คุณไม่สามารถกำหนดบัฟเฟอร์ใหม่ให้กับสตรีมเดียวกันและคุณต้องติดตามอายุการใช้งานและความเป็นเจ้าของของบัฟเฟอร์ภายนอก)

ผู้เชี่ยวชาญbasic_[io] fstreamและbasic_[io] stringstreamแต่ละคนมีตัวอย่างแบบเต็มของประเภทบัฟเฟอร์ที่เกี่ยวข้อง ซึ่งหมายความว่าอินสแตนซ์ของประเภทสตรีมแบบพิเศษจะทำงานกับบัฟเฟอร์ภายในเท่านั้นและไม่ใช่ประเภทอื่นแม้แต่ประเภทเดียวกันเท่านั้น การใช้ raw basic_[io] streamเป็นวิธีแก้ปัญหา (clunky) ของสิ่งนี้

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";
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.