将指针复制到包含表的对象时出现问题...保留了一些信息(字符串,例如skillName),但表中包含新的随机数据。我试了好几件事,但我还是不知道怎么回事,怎么办......请帮帮我。 :)
编辑:我已经编辑了整个帖子,正如WhozCraig所建议的那样使它成为MCVE(至少我试过)。 现在一切都在这段代码中,所以你可以复制它并亲自看看。由于某些原因,问题现在在不同的位置,但它仍然是相同的......
#include <iostream>
#include <string>
using namespace std;
class Skill
{
protected:
int const maxSkillLevel;
short skillLevel;
string skillName;
public:
Skill(string skillName) : maxSkillLevel(5){
skillLevel = 0;
this->skillName = skillName;
}
virtual ~Skill(){}
virtual int getMaxDmg(int i){ return 0; };
void increaseSkillLevel(int);
string getSkillName(){ return skillName; }
};
class OffensiveSkill : public Skill{
protected:
int *maxDmg;
public:
OffensiveSkill(string skillName, int maxDmg[]) : Skill(skillName){
this->maxDmg = maxDmg;
}
~OffensiveSkill(){}
int getMaxDmg(int i){ return maxDmg[i]; }
};
class Role{
protected:
string roleName;
Skill **skills;
public:
Role(string roleName){
skills = new Skill*[3];
this->roleName = roleName;
}
Role(Role* role){
this->skills = role->getSkills();
this->roleName = role->getRoleName();
}
Skill **getSkills(){ return skills; }
string getRoleName(){ return roleName; }
void setSkills(Skill* s1){ skills[0] = s1; }
};
class RoleGenerator{
protected:
Role *role;
public:
RoleGenerator(){
role = new Role("assassin");
int maxDmg[5] = { 30, 45, 60, 75, 90 };
OffensiveSkill* assassinate = new OffensiveSkill("Assassinate", maxDmg);
role->setSkills(assassinate);
cout << "maxDmg in RoleGenerator " << role->getSkills()[0]->getMaxDmg(0) << endl;
}
Role *getRoles(){ return role; }
};
int main(){
RoleGenerator* rg = new RoleGenerator();
Role *role = rg->getRoles();
cout << "maxDmg in main " << role->getSkills()[0]->getMaxDmg(0) << endl;
Role *copied = new Role(role);
//maxDmg here is different
cout << "maxDmg in after copying " << role->getSkills()[0]->getMaxDmg(0) << endl;
//but skill name is copied correctly
cout << "skill name " << role->getSkills()[0]->getSkillName() << endl;
}
答案 0 :(得分:1)
RoleGenerator:: RoleGenerator()
int maxDmg[5] = { 30, 45, 60, 75, 90 };
正作为地址传递给:
OffensiveSkill* assassinate = new OffensiveSkill("Assassinate", maxDmg);
通过以下方式保存该地址:
this->maxDmg = maxDmg;
RoleGenerator:: RoleGenerator()
返回后maxDmg
不再有效。以后取消引用保存的地址会调用未定义的行为。
如果副本足够,那么通过将数组复制到简单的成员数组或向量中,一种方法就可以实现这一点。有多种方法可以做到这一点。使用向量的一个体面的任意长度解决方案将是这样的:
#include <vector>
class OffensiveSkill : public Skill {
protected:
std::vector<int> maxDmg;
public:
template<size_t N>
OffensiveSkill(string skillName, int (&dmg)[N])
: Skill(skillName)
, maxDmg(dmg, dmg+N)
{
}
int getMaxDmg(int i) const { return maxDmg[i]; }
};
仅此一项就可以作为现有构造函数和类定义的替代品。如果需要,您可以通过提供备用构造函数来提供额外的灵活性,例如允许开始和结束迭代器直接传递给maxDmg
构造,int*
和size_t
长度等等。
我建议您修改索引成员getMaxDmg()
,以便(a)范围检查输入值,如果超出范围则抛出异常,并且(b)使用无符号数据类型(例如{{1你的索引。与你的问题无关,但值得考虑。
答案 1 :(得分:0)
这看起来很奇怪:
skills[0] = static_cast<OffensiveSkill*>(roleSkills[0]);
您需要包含更多代码。
但是,基于有限的信息,看起来你最好使用自定义的复制构造函数。编译器生成的复制构造函数不会为您执行深层复制。