C++ C++;

C++ C++;,c++,idioms,ostream,initialization-list,C++,Idioms,Ostream,Initialization List,以下代码来自: #包含//用于std::streambuf #包含//用于std::ostream 类FDF :public std::streambuf { 公众: 显式fdf(int-fd); //... }; 类fdostream :public std::ostream { 受保护的: fdf-buf; 公众: 显式fdostream(int-fd) :buf(fd),std::ostream(&buf)//这是不允许的。 //在std::ostream之前无法初始化buf。 {} //

以下代码来自:

#包含//用于std::streambuf
#包含//用于std::ostream
类FDF
:public std::streambuf
{
公众:
显式fdf(int-fd);
//...
};
类fdostream
:public std::ostream
{
受保护的:
fdf-buf;
公众:
显式fdostream(int-fd)
:buf(fd),std::ostream(&buf)//这是不允许的。
//在std::ostream之前无法初始化buf。
{}
//...
};

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

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

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

class C
{
  int a, b;
public:
  C() : b(1), a(b) {} // a is initialized before b!
};
代码不符合你的想法!首先初始化a,然后将b初始化为1。因此,它取决于声明的顺序,而不是初始化列表中的顺序:

int a, b;

现在,同样的想法也适用于在派生类成员之前初始化的基类。要解决此问题,您需要创建一个包含要从基类初始化的成员的类。当然,这个helper类必须在您实际从中派生的类之前。

事实上,只要基类构造函数(在本例中是
std::ostream(std::streambuf*bufptr)
不访问buf对象(aka
*bufptr),该代码就完全可以了
&buf
确实正确地指向了稍后将在其中构造
buf
的内存地址,因为
这个
指针在member-initializer-list中已经有效。它是指向成员变量的
指针,而不是
成员变量的
,这会产生很大的不同。请参阅我上面的评论。“你必须先调用基类构造函数”有点错误,因为不是你,而是语言在这样做。谢谢,我用指针纠正了这个问题。但是我认为你的第二点只是关于措辞,因为你必须把调用(或者你怎么称呼它)放到构造函数中(因为它需要一个参数)如果代码错误,即使代码在技术上是正确的,我也会认为它是错误的——可读性是关键:
int a, b;