我有一个Visual Studio 2008 c++应用程序,在那里我创建了一个自定义流buf和流实现。我使用了Angelika Langer给出的方法来创建流,具体如下:
class MyOutputStream_3 : private MyStreamBuf, public ostream {
public:
MyOutputStream_3() : ostream((MyStreamBuf*) this), ios(0) {};
virtual ~MyOutputStream_3() { sync(); }
// ...
};
但是,Visual Studio给我一个警告:
warning C4355: 'this' : used in base member initializer list
代码工作得很好,但是我担心编译器告诉我,我所做的要么在某些情况下可能会中断,要么可能不可移植。
这是我可以忽略在这种情况下,或者我应该做些什么来解决我的问题?
它警告你在初始化列表中使用this
,因为从技术上讲,this
还不存在,因为构造函数还没有完成执行(也没有任何成员对象的构造函数),并且将它传递给函数可能会在试图使用该对象(其中包含尚未调用构造函数的对象)时导致问题。
如果只是存储指针以供以后使用,代码应该可以工作。但是,当您回到这段代码并忘记不应该使用该指针时,您可能会犯错误,并且无法解释为什么您的程序会崩溃。
以下是该警告的Microsoft页面:http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
c++ 03标准在12.6.2/7 "初始化基和成员"的注释中有这一点:
注意:由于mem初始化式是在构造函数的作用域中求值的,因此this指针可以在mem初始化式的表达式列表中用来指向被初始化的对象。)
我认为发出警告是因为this
指针所引用的对象没有完全初始化,因此存在一些潜在的危险。只要你的基类在对象的未初始化部分被初始化之前不实际地使用,你就应该没问题。
警告(http://msdn.microsoft.com/en-us/library/3c594ae3.aspx)的MSDN文档中提到:
实际上,您已经将指向未构造对象的指针传递给了另一个构造函数。如果其他构造函数在this上访问任何成员或调用成员函数,结果将是未定义的。
顺便说一下,这只发生在您显式地在内存初始化器列表中使用this
时。传递尚未构造的成员变量的地址不会引发C4355异常。
如果你需要证明,看看fstream
的构造函数