首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过放置新对象转移对象所有权

通过放置新对象转移对象所有权
EN

Stack Overflow用户
提问于 2011-05-17 06:18:15
回答 2查看 356关注 0票数 0

我有一个Visual Studio2008 C++项目,其中包含一个管理无法复制的资源的类。我已经实现了引用结构语义(ala std::auto_ptr)。

代码语言:javascript
复制
class Test;

struct Test_Ref
{
    Test& ref_;
    Test_Ref( Test& t ) : ref_( t ) { };
private:
    Test_Ref& operator=( Test_Ref const& );
}; // struct Test_Ref

class Test
{
public:
    explicit Test( int f = 0 ) : foo_( f ) { };

    Test( Test& other ) : foo_( other.Detach() ) { };

    Test& operator=( Test& other )
    {
        foo_ = other.Detach();
        return *this;
    };

    Test( Test_Ref other ) : foo_( other.ref_.Detach() ) { };

    Test& operator=( Test_Ref other )
    {
        foo_ = other.ref_.Detach();
        return *this;
    };

    operator Test_Ref() { return Test_Ref( *this ); };

private:

    int Detach()
    {
        int tmp = foo_;
        foo_ = 0;
        return tmp;
    };

    // resource that cannot be copied. 
    int foo_;
}; // class Test

不幸的是,当我将此模式与使用placement-new的库一起使用时,我得到了一个编译器错误:

代码语言:javascript
复制
.\test.cpp(58) : error C2558: class 'Test' : no copy constructor available or copy constructor is declared 'explicit'
    .\test.cpp(68) : see reference to function template instantiation 'void Copy<Test>(T *,const T &)' being compiled
    with
    [
        T=Test
    ]

例如:

代码语言:javascript
复制
template< class T > inline void Copy( T* p, const T& val ) 
{
    new( p ) T( val );
}

int _tmain( int /*argc*/, _TCHAR* /*argv*/[] )
{
    Test* __p = new Test();
    Test __val;
    Copy( __p, __val );
    return 0;
}

我如何修改Test,使其可以与placement new一起使用,同时仍然保留其所有权语义?

谢谢,PaulH

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-17 06:29:28

专注于main函数,因为这应该表明你想要的语义,有两个大问题:首先,你没有分配内存,这意味着如果编译器处理代码,它将导致UB (将尝试在放置新操作中通过NULL地址调用Test的构造函数。

另一个问题对std::auto_ptr的用户来说是众所周知的:复制构造函数的签名采用非常量引用,这意味着您不能在常量对象上调用它。在另一端,您正在尝试调用Copy模板中的复制构造函数,该构造函数承诺不会更改第二个参数引用的对象:

代码语言:javascript
复制
template <typename T>
void Copy( T* p, T& o ) {
   new (p) T( o );         // would work, object is non-const
}

最后,我不确定是否由于复制到问题中,但我不确定您在开始时提供的引用包装器类的意图,所以您可能想要澄清一下。

票数 1
EN

Stack Overflow用户

发布于 2011-05-17 06:23:55

你的问题与新的位置无关。在void Copy中,您试图复制类型为Test的对象,但不允许复制。这就是问题所在。此外,您还尝试将new放在NULL上。由于常量的原因,您无法正确地实现该结构- operator test_ref()永远不能被调用,因为您接受了一个const T&,而它是一个非常数运算符。这意味着,除非你想在人们认为应该是复制的时候用动作给他们带来惊喜,否则你不能这样做。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6024095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档