C++函数之间传输字符串

C++ transferring a string between functions

本文关键字:字符串 传输 之间 函数 C++      更新时间:2023-10-16

我正在为我的课程编写一个程序,我必须制作一个随机的怪物生成器,然后打印怪物的参数。

我在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 它将执行所有加宽(如果需要(,这应该很好,无需担心注销边界,并且在您从函数返回或稍后执行相等时像魔术一样工作