我在努力实现族谱。我的类Person和Tree定义如下:
FamilyTree.hpp**:** 文件
using namespace std;
#include <string>
namespace family{
class Person{
public:
string name;
Person* mother;
Person* father;
Person(string name);
};
class Tree{
public:
Person* root;
Tree(string name);
Tree& addFather(string name1, string name2);
Tree addMother(string name1, string name2);
void display();
string relation(string name);
string find(string name);
void remove(string name);
};
};FamilyTree.cpp**:** 文件
#include "FamilyTree.hpp"
#include <string>
#include <iostream>
using namespace family;
// FUNCTIONS
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name);
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p;
}
}
// PERSON
family::Person::Person(string person_name){
name = person_name;
father = nullptr;
mother = nullptr;
};
// TREE
family::Tree::Tree(string name){
root = new Person(name);
};
family::Tree& Tree::addFather(string child, string father){
Person& child_found = findPerson(*root, child);
//cout<<"child_found.name:"<<child_found.name<<endl;
child_found.father = new Person(father);
return *this;
};
family::Tree family::Tree::addMother(string name1, string name2){return Tree("");};
void family::Tree::display(){};
string family::Tree::relation(string name){return "";};
string family::Tree::find(string name){return "";};
void family::Tree::remove(string name){};
int main(){
Tree t("X");
t.addFather("X", "Y");
t.addFather("Y","Z");
return 0;
}我从addFather()函数开始:addFather("child", "new father"),用于为现有的子项目添加新父亲。我使用findPerson()函数递归地实现了它,该函数返回子函数的Person对象,addFather() func创建新的Person并将其初始化为创建子函数。
在我添加了两个父亲后,我得到了非法指令(核心抛出)错误,应该是什么问题?
发布于 2020-04-05 14:50:09
如果打开警告,就会发现您并不总是从findPerson返回。在这个职能中
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p; // (2)
}
}第一个if-branch中标记为(1)的代码需要返回递归查找的人员,如下所示
return findPerson(*root.father, child_name);这应该能解决分段故障。
但是,在这个函数的最后一个分支中还有一个更深层次的问题,您将返回一个局部变量p的引用,标记为(2)。如果这样做,您将返回一个悬空引用,因为当函数返回时,p将超出作用域。
如果找不到人,您需要考虑这个函数应该做什么。
std::optional<Person>.
Person*,所以nullptr意味着找不到任何人。Person*发布于 2020-04-05 14:50:48
问题是不能返回对本地对象的引用。THis将导致未定义的行为。
当您添加一个新成员时,findPerson()将不会尝试返回这样一个本地对象p。这注定会失败。
这个设计不是最优的。可能的解决办法:
findPerson()的接口,使其返回指针。它要么返回指向某个人的有效指针,要么返回nullptr (如果没有找到)。这是一个常见的成语(在实际开发中,您将返回一个迭代器,但是如果您是从C++开始的,这暂时太复杂了)。如果没有发现任何异常,注意,如果有其他错误,我没有查看您的代码。我只是在第一次尝试找到当树是空的时候不存在的东西时就停了下来。
发布于 2020-04-07 16:20:15
它适用于父亲的搜索,但我需要它来遍历所有的树。当我加上母亲根的时候,核心又被倾倒了。
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
//cout<<root.name<<":1"<<endl;
return findPerson(*root.father, child_name);
return findPerson(*root.mother, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
//cout<<root.name<<":2"<<endl;
return root;
}else{
throw exception();
}
}https://stackoverflow.com/questions/61044069
复制相似问题