views:

207

answers:

2

I have a C++/CLI wrapper around native .lib and .h files. I use the AutoPtr class pretty extensively in the wrapper class to manage the unmanaged objects I create for wrapping. I have hit a roadblock with the copy constructor/assignment operator.

Using the AutoPtr class from Mr. Kerr: http://weblogs.asp.net/kennykerr/archive/2007/03/26/AutoPtr.aspx

He suggests the following(in the comments) to recreate the behavior of the assignment operator:

SomeManagedClass->NativePointer.Reset(new NativeType);

Which I believe is true. But when I compile my code:

ByteMessageWrap (const ByteMessageWrap% rhs)
{
     AutoPtr<ByteMessage> m_NativeByteMessage(rhs.m_NativeByteMessage.GetPointer());
};

ByteMessageWrap% operator=(const ByteMessageWrap% rhs)
{
     //SomeManagedClass->NativePointer.Reset(new NativeType);
     if (this == %rhs) // prevent assignment to self
        return *this;

     this->m_NativeByteMessage.Reset(rhs.m_NativeByteMessage.GetPointer());
     return *this;
};

-- I get the following errors:

error C2662: 'WrapTest::AutoPtr::GetPointer' : cannot convert 'this' pointer from 'const WrapTest::AutoPtr' to 'WrapTest::AutoPtr %'

Has anyone experienced similar issues?

A: 

Looking at Kenny Kerr's AutoPtr, it transfers ownership in its constructor -- essentially a "move" constructor rather than a copy constructor. This is analogous with std::auto_ptr.

If you really want to transfer ownership from rhs to this (i.e. leave rhs without it NativeByteMessage), you need to change your copy ctor into a move ctor.

Also, you need to use initialization syntax;

// warning - code below doesn't work
ByteMessageWrap (ByteMessageWrap% rhs)
    : m_NativeByteMessage(rhs.m_NativeByteMessage); // take ownership
{
}

ByteMessageWrap% operator=(ByteMessageWrap% rhs)
{
     //SomeManagedClass->NativePointer.Reset(new NativeType);
     if (this == %rhs) // prevent assignment to self
        return *this;

     m_NativeByteMessage.Reset(rhs.m_NativeByteMessage.Release());
     return *this;
}
Kim Gräsman
A: 

For further background on the answer, I removed the "const" keyword from the signature. I know that is not smiled upon in terms of code correctness for a copy ctor, but the CLR doesn't like it at all -- sort of belies the CLR at its core with memory management.

I wonder if it's possible to leave the const in the signature and then use GCHandle or pin_ptr to make sure memory doesn't move on you while performing the copy?

TomO
Go figure.I suppose you could try and create a deep copy of the message, provided m_NativeByteMessage is of a copyable type.But maybe you want to avoid gratuitous copies?
Kim Gräsman