这真令人困惑。我需要在程序中使用函数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的及其邻居关联。

08-18 11:04