我有一個Visual Studio 2008 C + +項目與管理資源,無法複製的類。我已經實現了參考轉換結構語義(ala std::auto_ptr
)。傳輸對象的所有權與安置新
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
不幸的是,當我使用這個模式與使用投放新的圖書館,我得到一個編譯錯誤:
.\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
]
例如:
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
這樣它可以與新的放置一起使用並仍保留其所有權語義?
感謝, PaulH
避免使用雙下劃線開頭的名稱,因爲這些名稱是爲實現(編譯器+標準庫)保留的名稱。另外,從'Test * p = NULL;'到'Test * p = new Test();'的變化並不能解決未定義的行爲,它只是將它換成另一個(這是UB構造同一個對象兩次,你正在分配內存並在'main'中調用構造函數的代碼,然後在'Copy'中再次調用構造函數(並且永不破壞或釋放內存......) – 2011-05-16 22:33:34