AutoPtr в смешанном режиме C ++ / CLI - PullRequest
0 голосов
/ 16 июля 2009

У меня есть оболочка C ++ / CLI для файлов .lib и .h. Я довольно широко использую класс AutoPtr в классе-обертке для управления неуправляемыми объектами, которые я создаю для обертывания. Я наткнулся на контрольно-пропускной пункт с помощью конструктора копирования / оператора присваивания.

Использование класса AutoPtr от Mr. Kerr: http://weblogs.asp.net/kennykerr/archive/2007/03/26/AutoPtr.aspx

Он предлагает следующее (в комментариях) для воссоздания поведения оператора присваивания:

SomeManagedClass->NativePointer.Reset(new NativeType);

Который я верю в правду. Но когда я компилирую свой код:

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;
};

- Я получаю следующие ошибки:

ошибка C2662: 'WrapTest :: AutoPtr :: GetPointer': невозможно преобразовать указатель this 'const WrapTest :: AutoPtr' для 'WrapTest :: AutoPtr%'

Кто-нибудь сталкивался с подобными проблемами?


Для получения дополнительной информации об ответе я удалил ключевое слово "const" из подписи. Я знаю, что это не рассматривается с точки зрения корректности кода для копирующего ctor, но CLR это совсем не нравится - своего рода противоречит CLR по своей сути с управлением памятью.

Интересно, можно ли оставить const в подписи, а затем использовать GCHandle или pin_ptr, чтобы убедиться, что память не перемещается на вас при выполнении копирования?

1 Ответ

0 голосов
/ 16 июля 2009

Глядя на AutoPtr Кенни Керра, он передает владение в своем конструкторе - по сути, это конструктор «перемещения», а не конструктор копирования. Это аналогично std :: auto_ptr.

Если вы действительно хотите передать право собственности с rhs на это (то есть оставить rhs без него NativeByteMessage), вам нужно изменить свой ctor-копию на ctor-ход.

Также вам нужно использовать синтаксис инициализации;

// 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;
}
...