AutoPtr в смешанном режиме C++/CLI

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

Использование класса AutoPtr от мистера Керра: 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» из подписи. Я знаю, что это не вызывает улыбки с точки зрения корректности кода для copy ctor, но CLR это совсем не нравится - своего рода противоречит CLR по своей сути с управлением памятью.

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


person TomO    schedule 16.07.2009    source источник
comment
Для ясности я получаю эту ошибку в обеих строках кода, вызывающего метод GetPointer().   -  person TomO    schedule 16.07.2009
comment
Хм... Я все еще думаю об этом. Какого поведения вы действительно хотите? Вы хотите, чтобы собственное байтовое сообщение ByteMessage отбрасывалось или клонировалось при копировании ByteMessage? Может быть, у ByteMessage не должно быть конструктора копирования, поскольку это управляемый класс — как насчет ICloneable?   -  person Kim Gräsman    schedule 16.07.2009


Ответы (1)


Глядя на 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;
}
person Kim Gräsman    schedule 16.07.2009