c ++中多态的对象数组更改了对象的详细信息

时间:2016-12-07 10:02:20

标签: c++ inheritance

我想制作一个"英雄"的对象矢量。对象

这是我做的宣言:

vector<hero*> arr;

这些是将对象输入数组的行(archer是英雄中的对象)

archer a('a'+to_string(numPlayer),gend,hit, point, point2); 

 this->arr.insert (this->arr.begin() + numPlayer, &a);

似乎一切正常,但是当我试图获得对象的健康时,它会显示6但它应该是100.为什么会这样? 我也尝试获取对象的名称但它给我分段错误。它为什么会发生?

这是hero.h:

 #ifndef HERO_H
#define HERO_H
#include <string>
#include <math.h>
#include <map>
#include <iostream>
#include "point2d.hpp"
//#include "enemy.hpp"
using namespace std;
#include "actors.hpp"

class hero:public actors{
    protected:
        string name; 
        int size; 
        char gender; 
        double health; 
        double hitting;
        point2d point, goal;
        double radius;


    public:

        hero(string name, char gender, double damage, point2d point, point2d goal);
        hero(const  hero &hero);
        ~hero();
        string getName();
        char getGender();
        double getDamage();
        point2d getPoint();
        double getHealth();

        void setName(string name);
        void setGender(char gender);
        void setDamage(double damage);
        void setHealth(double health);
        void setPoint(point2d point);
        string toString(); ///const in the end!!!!
        bool move(map<string, char> &matrix, vector<potion> potions );
        double getRadius();


       void hurt(double hit);

};

class warrior :public hero{
public:

    warrior(string name, char gender, double damage, point2d point, point2d point2);
    warrior(warrior &w);
    ~warrior();




};

class archer :public hero{
public:

    archer(string name, char gender,  double damage, point2d point, point2d point2);
    archer(archer &a);
    ~archer();



};

class wizard :public hero{
public:

    wizard(string name, char gender,  double damage, point2d point, point2d point2);
    wizard(wizard &a);
    ~wizard();
};

#endif

这些是弓箭手和英雄建造者

hero::hero(string name, char gender, double damage, point2d point,point2d point2){    
        this->name = name;
        this->gender=gender;
        this->health=100;
        this->hitting=damage;
        this->point = point2d(point);
        this->goal=point2d(point2);
        this->size=0;

}

archer::archer(string name, char gender, double damage, point2d point, point2d point2):
    hero(name, gender,  damage, point, point2) {

}

这是获取:cout<<this->arr.at(0)->getHealth();  //输出为6

cout<<this->arr.at(0)->getName(); 

// output:bash:line 12:23084 Segmentation fault $ file.o $ args

1 个答案:

答案 0 :(得分:1)

问题在于将英雄添加到vector

archer a('a' + to_string(numPlayer), gend, hit, point, point2); 
this->arr.insert(this->arr.begin() + numPlayer, &a);

在此处向本地变量插入指向存储的指针。当执行流离开当前块时,您的archer a将被销毁,并且它使用的内存可能会用于其他对象(这会更改以前的health字段以及指向该名称的指针)。有关详细信息,请查看this

要解决此问题,您应该在堆上分配您的弓箭手,如下所示:

archer* a = new archer('a' + to_string(numPlayer), gend, hit, point, point2); 
this->arr.insert(this->arr.begin() + numPlayer, a);

这段代码可能会正常工作,但还有一个缺陷:看起来容器arr应该拥有属于它的所有英雄,管理它们的生命时间以避免记忆(和其他资源)泄漏。要实现这一点,您可以使用智能指针,如下所示:

vector<unique_ptr<hero>> arr;
...
auto a = make_unique<archer>('a' + to_string(numPlayer), gend, hit, point, point2); 
this->arr.insert(this->arr.begin() + numPlayer, move(a));

有关智能指针的更多信息,请参阅以下内容:

  1. Cppreference documentation of make_unique
  2. Core c++ guidelines,他们对智能指针以及许多其他主题都有一些规则。