Groups | Blog | Home
all groups > visual c > september 2003 >

visual c : warning C4355: 'this' : used in base member initializer list


Carl Daniel [VC++ MVP]
9/28/2003 9:00:26 PM
[quoted text, click to view]

Keep in mind that C4355 is only a warning - the code has well defined
behavior as long as the base class constructor doesn't attempt to
dereference that 'this' value in the constructor body. If you're satisfied
that that's the case, then the solution is #pragma warning(disable:4355).

The compiler issues a warning for this usage because it's easy to invoke
undefined behavior when passing this to a base class constructor - as long
as you know what you're doing though, there's nothing technically wrong with
it.

-cd

Andrew Maclean
9/29/2003 11:55:29 AM
Please look at the sample code below first.

I understand the problem but I don't know how to get around it. I can see
that I am passing a pointer to an unconsructed object to another
constructor. How can I ensure that all construction is complete before using
the "this" pointer. Can someone give me some help on this?

Thanks in advance, Andrew.


Look at this example code:

// this class is an ultimate stream associated with a socket
template <class charT, class traits = std::char_traits<charT> >
class TCPGenericStream :
private TCPStreamBuffer<charT, traits>,
public std::basic_iostream<charT, traits>
{
public:

// this constructor takes 'ownership' of the socket wrapper if btakeowner
== true,
// so that the socket will be closed in the destructor of the
// TCPStreamBuffer object
explicit TCPGenericStream(TCPSocketWrapper &sock, bool takeowner = false)
: TCPStreamBuffer<charT, traits>(sock, takeowner),
std::basic_iostream<charT, traits>(this)
{
}

private:
// not for use
TCPGenericStream(const TCPGenericStream&);
TCPGenericStream& operator=(const TCPGenericStream&);
};


and

// this is even more specialized for use as a client
template <class charT, class traits = std::char_traits<charT> >
class TCPGenericClientStream :
private TCPSocketWrapper,
public TCPGenericStream<charT, traits>
{
public:

TCPGenericClientStream(const char *address, int port)
: TCPGenericStream<charT, traits>(*this, false)
{
TCPSocketWrapper::connect(address, port);
}

private:
// not for use
TCPGenericClientStream(const TCPGenericClientStream&);
TCPGenericClientStream& operator=(const TCPGenericClientStream&);
};

AddThis Social Bookmark Button