这真令人困惑。我需要在程序中使用函数CCountry::getName()。奇怪的是,当进行测试以查看它是否完全可以工作时,它只能在一个地方工作,但不能向下两行工作,而且我不知道为什么。例如...
while(line != "---" && line != "------")
{
CCountry *tempCountry = new CCountry(line);
cout << tempCountry->getName() << flush;
(*tempContinent).addCountry(*tempCountry);
getline(filestr, line);
}
作品。它按顺序列出了所有国家名称。然而...
while(line != "---" && line != "------")
{
CCountry *tempCountry = new CCountry(line);
(*tempContinent).addCountry(*tempCountry);
getline(filestr, line);
cout << tempCountry->getName() << flush;
}
不起作用。它甚至无法打印一个国家/地区名称,而是在调用getName()的行上抛出段错误。
作为进一步引用,这里有两个函数,getName()和addCountry()
string CCountry::getName()
{
return *name;
}
和
void CContinent::addCountry(CCountry country)
{
(*countries).push_back(country);
}
根据请求,这是CCountry构造函数:
CCountry::CCountry(string in_name)
{
name = new string;
*name = in_name;
player = new int;
*player = -1;
units = new int;
*units = 0;
neighbors = new list<CCountry>;
}
最佳答案
我可能会弄出一长串与此代码有关的错误,但是导致您的错误的原因最终是由于以下原因:
您的CCountry类未练习Rule of 3,因为它具有动态分配的成员,因此必须执行。 (顺便说一句,甚至不需要)。
您正在通过成员函数将CCounty对象添加到您的大洲,该成员函数按值计算国家/地区。那时会制作对象的浅拷贝。然后,将其推入大陆内部的容器中,这将产生另一个浅拷贝。在addCountry()退出时,原始的浅拷贝已被破坏,并且在此过程中,当您返回调用代码时,CCountry对象的内部结构已被破坏。因此,您的本地(本来就不会动态分配到第一名的地方)正式被清管了。
猜猜是什么...大陆容器中的那个也是。
我可能首先考虑CCountry对象本身。就我个人而言,我将在CContinent类中管理CCountry的邻居,而不是CCountry,因为无论如何,都是对CCountry对象的集合进行管理,但对每个对象都进行管理。如果您决定坚持使用当前模型,则CCountry的潜在替代方案可能是这样的:
class CCountry
{
public:
CCountry(const std::string& name)
: name(name), player(0), units(0)
{
}
// properties
const std::string& getName() const { return name; };
int getPlayer() const { return player; };
void setPlayer(int player) { this->player = player; };
int getUnits() const { return units; };
void setUnits(int units) { this->units = units; };
// neighbor access
const std::list<const CCountry*> getNeighbors() const
{
std::list<const CCountry*> res;
for (auto it=neighbors.begin(); it != neighbors.end(); ++it)
res.push_back(it->second);
return res;
}
// adding a new neighbor
void addNeighbor(const CCountry& other)
{
neighbors[ other.getName() ] = &other;
}
private:
std::string name;
int player;
int units;
std::map<std::string, const CCountry*> neighbors;
};
但是请注意:采用这样的模型(如您所见,您的原始模型)将存在潜在的陷阱,特别是CCountry可能指向技术上不拥有的另一个CCountry的指针。这就是为什么我希望由CContinent类本身来管理邻居关联的原因,因为它同时拥有CCountry的及其邻居关联。