2013-06-24 102 views
1

我在解決下面的代碼時遇到了麻煩。據我瞭解,由於複製問題,auto_ptr無法在STL中使用。但我無法使用C++ 11 unique_ptr來解決此問題。你能幫我解決這個問題嗎?向量中的自動指針(智能)

錯誤:

$ g++ -std=c++0x autoinvec.cpp 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h: In copy constructor âvna_data::vna_data(const vna_data&)â: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:214: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:214: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
autoinvec.cpp: In function âint main()â: 
autoinvec.cpp:39: note: synthesized method âvna_data::vna_data(const vna_data&)â first required here 
autoinvec.cpp:39: error: initializing argument 1 of âvoid Usethis::pushmydata(VNADATA)â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h: In member function âvna_data& vna_data::operator=(const vna_data&)â: 
autoinvec.cpp:11: instantiated from âvoid std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:100: instantiated from âvoid std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:747: instantiated from âvoid std::vector<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
autoinvec.cpp:27: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:219: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>& std::unique_ptr<_Tp, _Tp_Deleter>::operator=(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:219: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>& std::unique_ptr<_Tp, _Tp_Deleter>::operator=(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/vector:69, 
       from autoinvec.cpp:3: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc: In member function âvoid std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:314: note: synthesized method âvna_data& vna_data::operator=(const vna_data&)â first required here 

代碼:

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
auto_ptr<MyClass> ap1; 
auto_ptr<MyClass> ap2; 
string j; 
string m; 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(d); 
} 

int main() { 

Usethis u; 
VNADATA da; 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
da.ap1 = new MyClass(); 
da.ap2 = new MyClass(); 
u.pushmydata(da); 

return 0; 
} 

代碼的unique_ptr:

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
unique_ptr<MyClass> ap1; 
unique_ptr<MyClass> ap2; 
string j; 
string m; 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(move(d)); 
} 

int main() { 

Usethis u; 
VNADATA da; 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
da.ap1.reset(new MyClass); 
da.ap2.reset(new MyClass); 
u.pushmydata(da); 

return 0; 
} 
+3

你寫的代碼使用'auto_ptr',而不是'unique_ptr'。你不是說你已經意識到這種方式行不通? – jogojapan

+0

是的,但與unique_ptr我認爲我的用法是錯誤的,並給我錯誤。我希望如果有人能用unique_ptr或其他的方式給我提供關於基本代碼的建議。 – user1663533

+1

請提供代碼,嘗試用'unique_ptr'解決問題,否則任何答案都會嘗試爲您提供一些「auto_ptr」解決方案,該解決方案如您已經意識到的那樣容易出錯。換句話說,你應該嘗試解決'unique_ptr'問題,而不是'auto_ptr'問題。 –

回答

0

我想,你會讓你的生活更容易,如果你使用std::shared_ptrstd::make_shared

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
shared_ptr<MyClass> ap1; 
shared_ptr<MyClass> ap2; 
string j; 
string m; 
vna_data(shared_ptr<MyClass> ap1, shared_ptr<MyClass> ap2) : ap1(ap1), ap2(ap2) { 

} 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(d); 
} 

int main() { 

Usethis u; 
VNADATA da(std::make_shared<MyClass>(), std::make_shared<MyClass>()); 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
u.pushmydata(da); 
} 
1

unique_ptr是可移動的,但不可拷貝。您的Usethis::pushmydata方法的值爲VNADATA,該值嘗試複製unique_ptr,因此中斷。

編譯器點,你到第39行上使用pushmydata方法:

autoinvec.cpp: In function int main(): 
autoinvec.cpp:39: note: synthesized method vna_data::vna_data(const vna_data&) first required here 
autoinvec.cpp:39: error: initializing argument 1 of void Usethis::pushmydata(VNADATA) 

解決您的問題,改變Usethis::pushmydata的簽名;

void Usethis::pushmydata(VNADATA&& d) 
0

你的最後一行:

u.pushmydata(da); 

將需要複製。你應該像在之前一樣使用移動:

u.pushmydata(std::move(da)); 

它使代碼編譯。