大佬教程收集整理的这篇文章主要介绍了如何通过 return 语句更改指针指向的位置?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
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@我对使用原始指针很陌生,所以我可能只是不明白这里的问题是什么。如果有人能解释我做错了什么,我真的很感激。
Player
进行本地副本,因此如果匹配,将返回指向该副本的指针被发现。但是当当前迭代完成时,该copy 被销毁,因此您最终将返回一个悬空指针。要解决这个问题,您的循环需要对向量中的每个 Player
进行引用:
@H_607_2@for (Player &exisTingPlayer : *players)
@H_607_2@下一个问题是,如果未找到匹配项,则返回 new
ed 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@我还有一些建议可以改进您的代码:
std::unique_ptr
,std::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()
的迭代器来表示玩家不存在。但是要注意一个很大的缺点,一定要在修改容器和使迭代器失效之前进行测试。
#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,请注明来意。