Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用新放置转移对象所有权 我有一个VisualStudio 2008 C++项目,它具有一个管理无法复制的资源的类。我已经实现了引用结构语义传输(alastd::auto_ptr)_C++_Ownership_Placement New - Fatal编程技术网

使用新放置转移对象所有权 我有一个VisualStudio 2008 C++项目,它具有一个管理无法复制的资源的类。我已经实现了引用结构语义传输(alastd::auto_ptr)

使用新放置转移对象所有权 我有一个VisualStudio 2008 C++项目,它具有一个管理无法复制的资源的类。我已经实现了引用结构语义传输(alastd::auto_ptr),c++,ownership,placement-new,C++,Ownership,Placement New,不幸的是,当我将此模式用于使用placement new的库时,会出现编译器错误: .\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&g

不幸的是,当我将此模式用于使用placement new的库时,会出现编译器错误:

.\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
    ]
\test.cpp(58):错误C2558:类“test”:没有可用的复制构造函数或复制构造函数声明为“显式”
.\test.cpp(68):参见对正在编译的函数模板实例化“void Copy(T*,const T&)”的引用
具有
[
T=试验
]
例如:

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;
}
模板内联无效副本(T*p,const T&val)
{
新(p)T(val);
}
int _tmain(int/*argc*/,_TCHAR*/*argv*/[]))
{
测试*_p=新测试();
测试值;
复印件(p,val);
返回0;
}
如何修改
Test
,使其可以与placement new一起使用,并且仍然保留其所有权语义

谢谢,
保罗

你的问题与新职位无关。在
void Copy
中,您试图复制一个类型为Test的对象,但不允许复制。这就是问题所在。此外,您还尝试将新位置设置为空。由于constness-
运算符test\u ref()
无法调用,因此未能正确实现该结构,因为您使用了
常量T&
,并且它是一个非常量运算符。这意味着,除非你想在人们认为应该是拷贝的时候让他们惊讶,否则你不能这样做。

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

另一个问题是
std::auto_ptr
的用户所熟知的:复制构造函数的签名采用非常量引用,这意味着您无法在常量对象上调用它。另一方面,您尝试在
copy
模板内调用复制构造函数,该模板承诺不会更改第二个论点:

template <typename T>
void Copy( T* p, T& o ) {
   new (p) T( o );         // would work, object is non-const
}
模板
无效副本(T*p、T&o){
new(p)T(o);//将起作用,对象是非常量
}

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

修复了NULL上的新位置。是的,此对象的目标是在指定副本时执行移动。类似于
std::auto_ptr
。避免以双下划线开头的名称,因为这些名称是为实现保留的(编译器+标准库)。此外,将
Test*p=NULL;
更改为
Test*p=new Test();
并不能解决未定义的行为,它只是将其换成另一个(两次构造同一个对象是很困难的,在代码中分配内存并在
main
中调用构造函数,然后在
Copy
中再次调用构造函数(并且永远不要破坏或释放内存…)啊。我太专注于这个奇怪而神秘的新位置了,我完全错过了它正上方闪烁的巨大的
const
。谢谢。
template <typename T>
void Copy( T* p, T& o ) {
   new (p) T( o );         // would work, object is non-const
}