C++函数之间传输字符串
C++ transferring a string between functions
我正在为我的课程编写一个程序,我必须制作一个随机的怪物生成器,然后打印怪物的参数。
我在main
中使用此循环来生成然后打印数据:
for (g=0; g < m; g++)
{
tab[g] = &createRandomMonster(g);
printMonsterData(*tab[g]);
}
生成怪物的函数:
Monster createRandomMonster(int g)
{
ostringstream buffer;
buffer << ++g;
string name = buffer.str();
Monster nowypotwor{ name, MonsterType(rand() % 6 + 1), rand() % 25 + 5, (double)(10.0 + (rand() / (double)(RAND_MAX))*(30.0 - 10.0)) };
return nowypotwor;
}
而这个打印功能:
void printMonsterData(const Monster &potwor)
{
cout << "potwor: " << potwor.name << endl << "typ: " << getTypeName(MonsterType(potwor.type)) << endl << "atak: " << potwor.attack << endl << "zycie: " << potwor.health << endl << endl;
}
不过我不打印怪物的名字。如果我printMonsterData
createRandomMonster
,它就会这样做,但如果我在main
中这样做,我就没有这样做,我需要这样做。
错误的:
tab[g] = &createRandomMonster(g);
createRandomMonster
按值返回Monster
类实例,因此它返回的是一个临时对象,该对象在完整语句结束后立即销毁(即分号;
字符之后(。因此,如果您使用&
获取此临时对象的地址,则实际上获取的临时对象的地址很快就会被销毁,并且您放入tab[g]
悬空指针,导致在以后的代码执行中出现未定义的行为。
我建议您不要将Monster
对象存储为指针 tab
,而是按值存储:
std::vector<Monster> g;
如果需要指针,请将它们存储为:
std::vector<std::unique_ptr<Monster>> g;
并将createRandomMonster
更改为:
std::unique_ptr<Monster> createRandomMonster(int g)
{
ostringstream buffer;
buffer << ++g;
string name = buffer.str();
std::unique_ptr<Monster> nowypotwor = std::make_unique<Monster>(name, MonsterType(rand() % 6 + 1), rand() % 25 + 5, (double)(10.0 + (rand() / (double)(RAND_MAX))*(30.0 - 10.0)));
return nowypotwor;
}
和:
tab[g] = createRandomMonster(g);
你应该让函数createRandomMonster返回一个指向Monster(Monster*(的指针,或者更好的是,改变"tab"以持有一个智能指针(例如shared_ptr(而不是一个普通的指针,并从函数中返回它。
std::vector<std::shared_ptr<Monster>> tab;
std::shared_ptr<Monster> createRandomMonster(int g)
{
ostringstream buffer;
buffer << ++g;
string name = buffer.str();
return std::make_shared<Monster>(name,
MonsterType(rand() % 6 + 1), rand() % 25 + 5,
(double)(10.0 + (rand() / (double)(RAND_MAX))*(30.0 - 10.0)));
}
for (g=0; g < m; g++)
{
tab[g] = createRandomMonster(g);
printMonsterData(*tab[g]);
}
如果不需要多态行为,最好将值保存在向量中并将右值复制到制表符:
std::vector<Monster> tab;
for (g=0; g < m; g++)
{
tab[g] = createRandomMonster(g);
printMonsterData(tab[g]);
}
你需要捕获怪物返回。 即,Monster aMonster = createRandomMonster(g(;然后你可以说 tab[g] = &aMonster。
编辑 - 即使使用此解决方案,tab[g] 也只对 for 循环的生命周期有用,也就是 aMonster 的生命周期。这是通过引用操作的另一个结果。如果你在main的最外部范围内声明一个怪物,然后回到那个范围内,你可以绕过这个限制......
选项卡是怪物*数组而不是怪物数组有什么原因吗?成为后者会更有意义,除非我错过了什么......特别是因为您立即尊重它以将其传递给引用打印
将字符串传输到函数可以遵循下面提到的两种方式之一:
1( C 样式 - 声明一个数组(静态/全局/本地(,并将其地址(或 C++ 中的引用(作为指针传递给被调用的函数。如果动态分配,则改为传递指针
2( C++样式 - 使用 std::string 它将执行所有加宽(如果需要(,这应该很好,无需担心注销边界,并且在您从函数返回或稍后执行相等时像魔术一样工作