2013-10-07 85 views
1

因此,我認爲通過從原始指針轉換爲唯一指針並不難。然而,當我試圖爲自己做一件事時,我遇到了很多我不知道的問題。下面的這個例子將解釋更多我的意思。我從Visual Studio中得到了很多錯誤,我不知道如何解決它。我可以告訴我我做錯了什麼嗎?謝謝如何將原始指針轉換爲C++中的唯一指針

Contact.h 

#pragma once 
#include<iostream> 
#include<string> 
#include<memory> 

class Contact 
{ 
    friend std::ostream& operator<<(std::ostream& os, const Contact& c); 
    friend class ContactList; 

public: 
    Contact(std::string name = "none"); 

private: 
    std::string name; 
    //Contact* next;  
    std::unique_ptr<Contact> next; 
}; 

Contact.cpp

#include"Contact.h" 

using namespace std; 

Contact::Contact(string n):name(n), next(new Contact()) 
{ 
} 

ostream& operator<<(ostream& os, const Contact& c) 
{ 
    return os << "Name: " << c.name; 
} 

ContactList.h

#pragma once 
#include"Contact.h" 
#include<memory> 

using namespace std; 

class ContactList 
{ 
public: 
    ContactList(); 
    ~ContactList(); 
    void addToHead(const std::string&); 
    void PrintList(); 

private: 
    //Contact* head; 
    unique_ptr<Contact> head; 
    int size; 
}; 

ContactList.cpp

#include"ContactList.h" 
#include<memory> 

using namespace std; 

ContactList::ContactList(): head(new Contact()), size(0) 
{ 
} 

void ContactList::addToHead(const string& name) 
{ 
    //Contact* newOne = new Contact(name); 
    unique_ptr<Contact> newOne(new Contact(name)); 

    if(head == 0) 
    { 
     head.swap(newOne); 
     //head = move(newOne); 
    } 
    else 
    { 
     newOne->next.swap(head); 
     head.swap(newOne); 
     //newOne->next = move(head); 
     //head = move(newOne); 
    } 
    size++; 
} 

void ContactList::PrintList() 
{ 
    //Contact* tp = head; 
    unique_ptr<Contact> tp(new Contact()); 
    tp.swap(head); 
    //tp = move(head); 

    while(tp != 0) 
    { 
     cout << *tp << endl; 
     tp.swap(tp->next); 
     //tp = move(tp->next); 
    } 
} 

我通過交換功能交換之間的內容更新指針。

這是所有我得到

Error 2 error LNK1120: 1 unresolved externals E:\Fall 2013\CPSC 131\Practice\Practice\Debug\Practice.exe 1 

錯誤1錯誤LNK2019錯誤:無法解析的外部符號 「公用:__thiscall ContactList ::〜ContactList(無效)」(?? 1ContactList @@ QAE @ XZ)在函數「public:void * __thiscall ContactList ::`標量刪除析構函數'(unsigned int)」(?? _ GContactList @@ QAEPAXI @ Z)中引用E:\ Fall 2013 \ CPSC 131 \ Practice \ Practice \ Practice \ ContactListApp.obj

+0

如果你粘貼了錯誤,那就更好了。或者第一個,如果他們很多。 –

+0

我看到的一個問題,我相信你必須使用std :: move來分配唯一的ptrs。 http://en.cppreference.com/w/cpp/memory/unique_ptr。雖然在你的構造函數中初始化爲nullptr應該可以工作。這將有助於粘貼您收到的錯誤。 – Kindread

+0

@ AdriC.S .:我在那裏複製並粘貼錯誤。你會看看並告訴我我做錯了什麼嗎?謝謝 –

回答

3

unique_ptr有空的構造函數和nullptr的構造函數,它沒有提到任何關於0的內容。

constexpr unique_ptr(); 
constexpr unique_ptr(nullptr_t); 
explicit unique_ptr(pointer p); 
unique_ptr(pointer p, /* see below */ d1); 
unique_ptr(pointer p, /* see below */ d2); 
unique_ptr(unique_ptr&& u); 
template< class U, class E > 
unique_ptr(unique_ptr<U, E>&& u); 
template< class U > 
unique_ptr(auto_ptr<U>&& u); 

此外,您將要使用void swap(unique_ptr& other)交換unique_ptrs之間的指針,而不會像operator=那樣將它們解構爲指針。再次考慮到所有這些,你應該仔細看看cppreference.com unique_ptr頁面瞭解它是如何工作的。

在鏈接列表的第二個音符,如果我是你,我會使用原始指針。

+0

_關於鏈表的第二個注意事項,如果我是你,我會使用原始指針._ - 你能給出這個建議的解釋嗎? – ComicSansMS

+0

@ComicSansMS當你可以手動刪除指針時,我根本沒有在鏈表中看到使用unique_ptr的要點。我認爲這是一種不必要的性能開銷,因爲它們不會帶來任何效用,除非使其更復雜,例如上述情況。如我錯了請糾正我。 –

+0

我的推理與你的相反:在使用原始指針時,防止可能會拋出異常的代碼中的泄漏相當困難。所以我認爲這是一個不必要的複雜開銷,不要在這裏使用unique_ptr。在任何現代編譯器中,unique_ptr的性能開銷都應該爲0,所以這對我來說沒有任何爭論。 – ComicSansMS