程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何通过 return 语句更改指针指向的位置?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何通过 return 语句更改指针指向的位置??

开发过程中遇到如何通过 return 语句更改指针指向的位置?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何通过 return 语句更改指针指向的位置?的解决方法建议,希望对你解决如何通过 return 语句更改指针指向的位置?有所启发或帮助; @H_607_2@我有一个包含 ID 字符串的 Player 对象。我试图通过遍历玩家列表来检查玩家是否已经存在。如果播放器已经存在,我想返回现有的播放器,否则我将创建一个 Player 对象的新实例。

Player *playerExists(const std::string &playerID,const std::vector<Player>* players)
{
    for (Player exisTingPlayer : *players)
    {
        if (exisTingPlayer.playerID == playerID)
        {
            std::cout << "Player " << exisTingPlayer.name << " exists" << std::endl;
            return &exisTingPlayer;
        }
    }
    return new Player();
}
@H_607_2@问题似乎出在 return 语句中。我不知道如何将特定对象返回到指针。这似乎是我发现不会出错的唯一方法(谈论 return 语句中的 & sing)。

Player* player = playerExists("SomEID",listofPlayers);
listofPlayers->push_BACk(*player);
delete player;
@H_607_2@我对使用原始指针很陌生,所以我可能只是不明白这里的问题是什么。如果有人能解释我做错了什么,我真的很感激。

解决方法

@H_607_2@这段代码有几个问题。

@H_607_2@循环的每次迭代都会对向量中的 Player 进行本地副本,因此如果匹配,将返回指向该副本的指针被发现。但是当当前迭代完成时,该copy 被销毁,因此您最终将返回一个悬空指针。要解决这个问题,您的循环需要对向量中的每个 Player 进行引用

@H_607_2@for (Player &exisTingPlayer : *players)

@H_607_2@下一个问题是,如果未找到匹配项,则返回 newed Player。问题在于调用者会无条件delete处理返回的 Player*,无论它是否被 new 处理。该向量拥有它所持有的 Player 个对象,因此delete其中一个对象是未定义行为

@H_607_2@更好的设计选择是如果未找到匹配项,则让 playerExists() 返回 nullptr。然后调用者可以根据返回的是 Player 还是 nullptr 执行不同的操作,例如:

Player* playerExists(const std::string &playerId,const std::vector<Player>* players)
{
    for (Player &exisTingPlayer : *players)
    {
        if (exisTingPlayer.playerId == playerId)
        {
            std::cout << "Player " << exisTingPlayer.name << " exists" << std::endl;
            return &exisTingPlayer;
        }
    }
    return nullptr;
}
Player* player = playerExists("SomEID",listOfPlayers);
if (player) {
    // ID found,use player as needed...
    listOfPlayers->push_BACk(*player); // why re-add a player that is already in the list???
} else {
    // ID not found,do something else...
    listOfPlayers->push_BACk(Player{}); // why add a blank player???
}
, @H_607_2@解决这个问题的不同方法。最大的问题可能在这一行:

for (Player exisTingPlayer : *players)
@H_607_2@它正在复制(我认为)已经在收藏中的玩家。

@H_607_2@当你执行 return &exisTingPlayer; 时......好吧,它在堆栈上返回一个对象。不好的事情会发生

@H_607_2@你最好迭代集合并返回一个迭代器,恕我直言......也许......

std::vector<Player>::const_iterator playerExists(const std::string &playerId,const std::vector<Player>& players)
{
    std::vector<Player>::const_iterator it = players.begin();
    for (; it != players.end(); ++it)
    {
        if (it->playerId == playerId)
        {
            std::cout << "Player " << it->name << " exists" << std::endl;
            break;
        }
    }
    return it;
}
@H_607_2@您可以在返回后随时测试

@H_607_2@对于返回的迭代器,您必须对其进行处理...

auto it = playerExists(playerId,players);
if (it == players.end())
{
   // not found
} else {
   // found
}
, @H_607_2@你的问题是:

for (Player exisTingPlayer : *players)
@H_607_2@在 for 循环的每次迭代中,exisTingPlayer 是存储在 范围内的局部变量中的玩家的副本 >for 循环。您正在返回一个指向局部变量的指针,该变量在每次循环迭代后都会被销毁。

@H_607_2@为了避免复制,请使用引用

for (Player &exisTingPlayer : *players)
@H_607_2@此处,exisTingPlayer 是对真实玩家的引用。这就是您对函数原型中的 const std::string 所做的。

@H_607_2@我还有一些建议可以改进您的代码:

    @H_197_140@ @H_607_2@避免使用原始 C 指针,C++ 为您提供了一些工具,以(大大)不易出错的方式获得相同的功能,因此更安全。如果您不需要我在代码中看到的 NULL,参可能会更好。否则,您应该虑智能指针(std::unique_ptrstd::shared_ptr。在您的情况下,我会通过引用传递 players 而不是指针。

    @H_197_140@ @H_607_2@std::vector 可能不是最好的容器。 选择正确的容器可能很困难。目前您正在遍历整个数组以通过他的 ID 找到玩家。您应该使用使用哈希表的 std::unordered_map<std::string,Player> 并可能加快查找时间。 我还会使用 std::a_container_class<Player> 的 typedef 来避免在您更改容器类型或稍后从头开始编写时进行大量代码重写。

    @H_197_140@ @H_607_2@复制 Player 有意义吗?如果没有,显式删除 copy constructor 和 copy assignment operator,编译器会抛出错误想要复制 Player请注意,这是我经常做的设计选择,同一播放器的多个实例是正常的,具体取决于您的对象设计。

    @H_197_140@ @H_607_2@我对 return new Player(); 表示怀疑。如果没有玩家存在,为什么要返回一个新玩家?根据我的个人解释(可能完全错误),我会返回一个迭代器。不涉及指针,您可以“取消引用”迭代器以获取对找到的玩家的引用,并且通过返回等于 players.end() 的迭代器来表示玩家不存在。但是要注意一个很大的缺点,一定要在修改容器和使迭代器失效之前进行测试。

@H_607_2@根据我自己的设计选择,我制作了一个稍微未经测试且较短的函数版本:

#include <unordered_map>
typedef std::unordered_map<std::string,Player> PlayerCollection;
/* ... */
PlayerCollection::const_iterator playerExists(const std::string &playerId,const PlayerCollection &players)
{
    return players.find(playerId);
}
@H_607_2@请记住,我的建议是自以为是,并不是绝对的事实。 阅读其他有不同想法的答案。

大佬总结

以上是大佬教程为你收集整理的如何通过 return 语句更改指针指向的位置?全部内容,希望文章能够帮你解决如何通过 return 语句更改指针指向的位置?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。