Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 代码行不';两行之后我就不工作了_C++_List_Function - Fatal编程技术网

C++ 代码行不';两行之后我就不工作了

C++ 代码行不';两行之后我就不工作了,c++,list,function,C++,List,Function,这令人困惑。我需要在我的程序中使用一个函数CCountry::getName()。奇怪的是,当测试它是否工作时,它在一个地方工作,但在两行下不工作,我不知道为什么。例如 while(line != "---" && line != "------") { CCountry *tempCountry = new CCountry(line); cout << tempCountry->getName() << f

这令人困惑。我需要在我的程序中使用一个函数CCountry::getName()。奇怪的是,当测试它是否工作时,它在一个地方工作,但在两行下不工作,我不知道为什么。例如

while(line != "---" && line != "------")
    {
        CCountry *tempCountry = new CCountry(line);
        cout << tempCountry->getName() << flush;
        (*tempContinent).addCountry(*tempCountry);
        getline(filestr, line);

    }

根据请求,以下是cccountry构造函数:

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::CCountry(名称中的字符串)
{
name=新字符串;
*姓名=姓名;
玩家=新整数;
*玩家=-1;
单位=新整数;
*单位=0;
邻居=新列表;
}

您是否可能在CCountry的构造函数中造成某种覆盖?听起来很像。

我可以用这段代码列出一长串错误,但导致您出错的原因最终是以下原因:

您的CCountry类没有练习,它必须练习,因为它有动态分配的成员。(顺便说一句,甚至不需要)

您正在通过一个成员函数将Accounty对象添加到您的大陆,该函数按值获取国家。此时将制作对象的浅拷贝。然后将其推入大陆内的容器中,从而生成另一个浅拷贝。在addCountry()退出时,原始的浅层副本将被销毁,在这个过程中,当您返回到调用代码时,CCCountry对象的内部已被销毁。因此,您的本地(不应该在第一个位置动态分配,顺便说一句)是正式的软管

猜猜看。。。你们大陆集装箱里的那个也是

我可能会首先考虑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() {
    delete name;
    delete player;
    delete units;
    delete neighbors;
}
CCountry(CCountry const &that) :
    name(that.name),
    player(that.player),
    units(that.units),
    neighbors(that.neightbors)
{ }
class CCountry {
    string name;
    int player;
    int units;
    list<CCountry *> neighbors;
};
类国家
{
公众:
CCountry(常量标准::字符串和名称)
:姓名(姓名)、玩家(0)、单位(0)
{
}
//性质
const std::string&getName()const{return name;};
int getPlayer()常量{return player;};
void setPlayer(int player){this->player=player;};
int getUnits()常量{return units;};
void setUnits(整数单位){this->units=units;};
//邻居访问
常量std::list getneights()常量
{
std::list res;
for(auto it=neights.begin();it!=neights.end();+it)
res.push_back(它->秒);
返回res;
}
//添加新邻居
无效添加邻居(施工国家和其他)
{
邻居[other.getName()]=&other;
}
私人:
std::字符串名;
国际球员;
整数单位;
地图邻居;
};

但请注意:采用这样的模型(正如您所看到的,您的原始模型)会有潜在的缺陷,特别是一个国家可能有指向另一个技术上不属于它的国家的指针。这就是为什么我希望邻居关联由CContinent类本身管理,因为它同时拥有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() {
    delete name;
    delete player;
    delete units;
    delete neighbors;
}
CCountry(CCountry const &that) :
    name(that.name),
    player(that.player),
    units(that.units),
    neighbors(that.neightbors)
{ }
class CCountry {
    string name;
    int player;
    int units;
    list<CCountry *> neighbors;
};
但我怀疑您没有为
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() {
    delete name;
    delete player;
    delete units;
    delete neighbors;
}
CCountry(CCountry const &that) :
    name(that.name),
    player(that.player),
    units(that.units),
    neighbors(that.neightbors)
{ }
class CCountry {
    string name;
    int player;
    int units;
    list<CCountry *> neighbors;
};
现在,
CContinent::addCountry
被定义为接受
CCountry
,而不是
CCountry&
。因此,当您执行
(*tempCountry).addCountry(*tempCountry)
时,您的程序会使用编译器定义的
CCountry
复制构造函数来生成
*tempCountry
的(临时)副本

因此,现在您的程序有两个独立的
CCountry
实例:一个由
tempCountry
指向,另一个在
CContinent::addCountry
country
参数中。但是由于编译器定义的复制构造函数的工作方式,两个实例都有
name
成员变量指向同一
string
实例

删除临时副本时,其析构函数将删除该字符串实例。现在,
tempCountry
指向的实例在其
name
成员变量中有一个悬空指针。当您尝试取消引用
getName
中的悬空指针时,该行为未定义,并导致分段错误

将您的
名称
播放器
单位
邻居
成员变量更改为非指针。它们应该是普通类型,如下所示:

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() {
    delete name;
    delete player;
    delete units;
    delete neighbors;
}
CCountry(CCountry const &that) :
    name(that.name),
    player(that.player),
    units(that.units),
    neighbors(that.neightbors)
{ }
class CCountry {
    string name;
    int player;
    int units;
    list<CCountry *> neighbors;
};
类国家{
字符串名;
国际球员;
整数单位;
列出邻居;
};

您可能还希望更改函数以获取引用而不是副本。

在您的国家/地区的构造函数中,您使用
新字符串分配名称,在析构函数中,您可能使用
删除名称来释放名称。我不知道您为什么需要这样做,将
string
存储为
CCountry
name
成员可能更简单。当您将
CCountry
作为参数传递给
CContinent::addCountry
时,将创建并删除它的临时副本,这将导致删除在
CCountry
的多个实例之间共享的
CCountry::name
。为了避免这种情况,您需要使用
string
而不是
string*
作为
CCountry
的成员
name
,或者实现您自己的CCountry复制构造函数。

此代码存在许多问题,但对于初学者来说,
CCountry
是否具有值语义,或者它是实体类型。 在第一种情况下,不应该有指向它的指针,或者 使用
new
动态分配它。你应该确保 它可以被正确地复制和使用