2016-05-25 60 views
-1

我有一個C++類項目。目標是在插入linked list時對電話簿(txt文件)進行排序。C++ - 類構造函數創建對象,但構造的結果是不同的

這裏是類:

class Person 
{ 
    public: 
     string Name 
     string Firstname; 
     string Adress; 
     int PostalCode; 
     string Telephone; 
     Person(); 
     ~Person(); 
}; 

class Link 
{ 
    friend class List; 
    Link *next; 
    Person *pers; 
    public: 
     Link(); 
     Link(string data); 
}; 

class List 
{ 
    // debut is the start of the chained list 
    Link *start; 
    public: 
     List(string data) 
     { 
      start = NewLinkPerson(data, NULL); 
     } 
}; 

Link::Link(string data) 
{ 
    next = NULL; 
    Person p; 
    p.put_data(data); 
    pers = &p; 
} 

Link::Link() 
{ 
    next = NULL; 
    Person p; 
    pers = &p; 
} 

然後,功能NewLinkPerson詳列如:

Maillon * NewLinkPerson(string data, Maillon *ssuiv) 
{ 
    Maillon * nouveau = new Maillon(data); 
    nouveau->suiv = ssuiv; 
    return nouveau; 
} 

的問題是創建的對象不是我點播的節目他的人創造。如果我在構造函數中輸出Person類型的對象pers,它將填充我詢問的數據。 但是,當它離開構造函數時,數據就消失了,並且從內存中填充了隨機字符串。

什麼可能導致此問題?我嘗試了很多東西,但是它們都沒有工作,所有這些主要都返回了一個分段錯誤。

編輯:一個功能我忘了放在那裏:

void Person::put_data(string data) 
{ 
    int sep1 = data.find("|"); 
    int sep2 = data.find("|", sep1+1); 
    int sep3 = data.find("|", sep2+1); 
    int sep4 = data.find("|", sep3+1); 
    Name = data.substr(0, sep1); 
    Firstname = data.substr(sep1+1, sep2-sep1-1); 
    Adress = data.substr(sep2+1, sep3-sep2-1); 
    Telephone = data.substr(sep4+1, data.npos); 
    string ccode = data.substr(sep3+1, sep4-sep3-1); 
    PostalCode = std::stoi(ccode.c_str()); 
} 

編輯2:翻譯成英文

+0

'pers =&p;'編譯? – NathanOliver

+0

「問題是創建的對象不是我命令他做的那個。」 < - 這句話甚至意味着什麼?他是誰」? – Barry

+0

@NathanOliver是的,g ++編譯器告訴我說,因爲對象pers是一個指針,在文章中忘了*,現在編輯 –

回答

6

你的代碼是未定義行爲

Link::Link(string data) 
{ 
    next = NULL; 
    Person p; 
    p.put_data(data); 
    pers = &p; 
} 

Link::Link() 
{ 
    next = NULL; 
    Person p; 
    pers = &p; 
} 

在兩個構造在上面的代碼中你創建了一個本地的Person,p,然後你有pers指向它。構造函數結束後p超出範圍,被破壞,現在pers指向一個不再存在的對象。之後的任何解除引用pers它仍然指向被刪除的對象是未定義的行爲。

要解決這個問題,只需刪除指針pers。如果你將它存儲爲一個值,那麼你不需要任何動態內存分配,並且你可以擺脫指針語法。鏈接應該是

class Link 
{ 
    friend class List; 
    Link *next; 
    Person pers; // no pointer here 
    public: 
     Link(); 
     Link(string data); 
}; 

然後構造函數可以像

Link::Link(string data) 
{ 
    next = NULL; 
    pers.put_data(data); 
} 

Link::Link() 
{ 
    next = NULL; 
} 

被定義。如果你必須有pers爲指針,那麼你可以分配永久存儲它new。如果你這樣做,那麼你需要確保你在類的析構函數中有delete,並且你有複製語義。有關此更多信息,請參閱What is The Rule of Three?

+0

但是,如果我不在構造函數對象中創建一個人,那麼我可以在哪裏創建它,並且語法是什麼?我試過這個:'(鏈接的名稱) - > pers = new Person;'但編譯時引發了一個錯誤。 –

+0

@ThibaultdeVillèle在鏈接的構造函數中使用'new':pers'是'Link'的私有成員,不能從'Link'的實例外部訪問 – KABoissonneault

+0

@KABoissonneault沒有理由使用new當我們可以擺脫它作爲一個指針時,爲'pers'。 – NathanOliver

相關問題