I have a Visual Studio 2008 C++ application where I've created a custom streambuf and stream implementation. I've used an approach given by Angelika Langer for creating the stream detailed below:
class MyOutputStream_3 : private MyStreamBuf, public ostream {
public:
MyOutputStream_3() : ostream((MyStreamBuf*) this), ios(0) {};
virtual ~MyOutputStream_3() { sync(); }
开发者_如何学运维 // ...
};
But, Visual Studio gives me a warning:
warning C4355: 'this' : used in base member initializer list
The code works fine, but I'm worried the compiler is informing me that what I've done either could break under some circumstances or may be non-portable.
Is this something I can ignore in this instance or what should I do to fix my issue?
It's warning you about the use of this
in the initializer list because technically, this
doesn't exist yet because the constructor hasn't finished executing yet (nor have the constructors of any member objects) and passing it to a function could cause problems when they try to use that object (which contains objects whose constructors haven't been called).
The code should work if you're just storing the pointer for use later. But when you come back to this code and forget that you're not supposed to use that pointer, you might make a mistake and not be able to explain why your program is crashing.
Here is the Microsoft page for that warning: http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
The C++03 standard has this bit in a note for 12.6.2/7 "Initializaing bases and members":
[Note: because the mem-initializer are evaluated in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. ]
I think the warning is issued becuase the object being referred to by the this
pointer isn't fully initialized so there's some potential danger. As long as your base doesn't actually use the uninitialized parts of the object until after they're initialized, you should be fine.
As the MSDN docs for the warning (http://msdn.microsoft.com/en-us/library/3c594ae3.aspx) mention:
In effect, you've passed a pointer to an unconstructed object to another constructor. If those other constructors access any members or call member functions on this, the result will be undefined.
Incidentally, this only happens when you explicitly use this
in the mem-initializer list. Passing the address of a member variable that has not yet been constructed does not raise C4355.
Take a look at fstream
's constructor if you need proof.
精彩评论