2016-05-25 59 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

相关问题