AutoPtr在C ++ / CLI混合模式下

时间:2022-06-28 05:26:56

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.

我有一个围绕本机.lib和.h文件的C ++ / CLI包装器。我在包装器类中广泛使用AutoPtr类来管理我为包装创建的非托管对象。我遇到了使用复制构造函数/赋值运算符的障碍。

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

使用Kerr先生的AutoPtr类: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 %'

错误C2662:'WrapTest :: AutoPtr :: GetPointer':无法将'this'指针从'const WrapTest :: AutoPtr'转换为'WrapTest :: AutoPtr%'

Has anyone experienced similar issues?

有没有人遇到类似的问题?


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.

有关答案的进一步背景,我从签名中删除了“const”关键字。我知道,对于复制文件的代码正确性而言,并没有微笑,但CLR根本不喜欢它 - 有点掩盖了CLR的核心内存管理。

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?

我想知道是否可以将const留在签名中然后使用GCHandle或pin_ptr来确保在执行复制时内存不会移动到你身上?

1 个解决方案

#1


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.

看看Kenny Kerr的AutoPtr,它在构造函数中转移所有权 - 实质上是一个“移动”构造函数而不是复制构造函数。这与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.

如果你真的想将所有权从rhs转移到这个(即保留rhs而没有它NativeByteMessage),你需要将你的副本ctor变成一个移动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;
}

#1


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.

看看Kenny Kerr的AutoPtr,它在构造函数中转移所有权 - 实质上是一个“移动”构造函数而不是复制构造函数。这与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.

如果你真的想将所有权从rhs转移到这个(即保留rhs而没有它NativeByteMessage),你需要将你的副本ctor变成一个移动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;
}