【问题标题】:Base-from-Member Idiom in C++C++ 中的 Base-from-Member 成语
【发布时间】:2011-01-27 11:51:13
【问题描述】:

以下代码来自here

#include <streambuf>  // for std::streambuf
#include <ostream>    // for std::ostream

class fdoutbuf
    : public std::streambuf
{
public:
    explicit fdoutbuf( int fd );
    //...
};

class fdostream
    : public std::ostream
{
protected:
    fdoutbuf buf;
public:
    explicit fdostream( int fd ) 
        : buf( fd ), std::ostream( &buf ) // This is not allowed. 
                                          // buf can't be initialized before std::ostream.
        {}
    //...
};

我真的不明白这个评论。为什么“不能在std::ostream之前初始化buf”?我可以使用一些帮助来理解这一点吗?

【问题讨论】:

  • 实际上,代码完全没问题,只要基类构造函数(在这种情况下 std::ostream(std::streambuf* buf_ptr) 不访问 buf 对象(又名 *buf_ptr)&amp;buf 确实正确指向内存)稍后将构造buf 的地址,因为this 指针在成员初始化器列表中已经有效。

标签: c++ idioms ostream initialization-list


【解决方案1】:

初始化的顺序由声明类成员的顺序决定,继承的类在所有这些之前。举一个简单的例子来说明基本问题,而不涉及继承:

class C
{
  int a, b;
public:
  C() : b(1), a(b) {} // a is initialized before b!
};

代码不符合你的想法! a 先初始化,然后 b 初始化为 1。所以这取决于声明的顺序而不是初始化列表中的顺序:

int a, b;

现在,同样的想法适用于在派生类成员之前初始化的基类。为了解决这个问题,你创建了一个你固有的类,其中包含你想要从基类初始化的成员。当然,这个助手类必须在你实际派生的那个之前。

【讨论】:

    【解决方案2】:

    您必须在初始化成员变量之前调用基类构造函数,但是您将指向 buf 的指针(此时未定义的成员变量)传递给此构造函数。

    【讨论】:

    • 它是pointer to a member variable,而不是member variable,这有很大的不同.. 请参阅我上面的评论。 “你必须先调用基类构造函数”有点错误,因为不是你而是语言这样做。
    • 谢谢,我用指针纠正了这个问题。 Bur 我认为您的第二点只是措辞,因为无论如何您都必须将调用(或无论如何命名)放到那里的构造函数中(因为它需要一个参数),如果将代码放入,我会认为它是错误的顺序错误,即使它在技术上是正确的 - 可读性是关键:-)
    猜你喜欢
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多