初始化后 const_iterator 成员变量未指向向量成员变量的开头

如何解决初始化后 const_iterator 成员变量未指向向量成员变量的开头

我正在尝试为纸牌游戏 Avalon 实现贝叶斯估计器。游戏有五轮,每一轮最多包含五个不同玩家提出的五个提案。如果提议被接受,玩家将继续进行任务,游戏进入下一轮。在上一轮结束之前,下一轮将有哪5名选手被提名,尚不得而知。我想跟踪使用迭代器提出团队建议的当前玩家,但不知何故它最终指向无处。具体来说,在调用 round1 的构造函数中,迭代器 Round::proposer 正确指向 &PlayerA,即 Round::proposers 的开头。但是,当我将此实例(或它的副本?)添加到 Game::rounds 时,proposer 的 Round 成员 Game::rounds.back() 无处指向,即使 Round 成员 proposers仍然是正确的。为什么会这样?在执行过程中,当然会在调用(*Round::proposer)->make_proposal(); 时抛出读访问冲突异常。对于这个冗长的问题,我深表歉意,但产生错误似乎需要两个间接级别。

// Player.h
#include <string>

class Player
{
private:
    std::string name;
public:
    Player(std::string name) : name(name) {};
    void make_proposal() const {};
};
// Round.h
#include "Player.h"
#include <vector>

class Round
{
private:
    std::vector<const Player*> proposers;
    std::vector<const Player*>::const_iterator proposer;
public:
    Round(std::vector<const Player*> proposers) : proposers(proposers),proposer(Round::proposers.begin()) {};

    void next_proposal() { (*Round::proposer)->make_proposal(); };
};
// Game.h
#include "Round.h"
#include <vector>

class Game
{
private:
    std::vector<Player*> players;
    std::vector<Player*>::iterator active_player;
    std::vector<Round> rounds;
public:
    Game(std::vector<Player*> players);

    void advance_player();
    void next_round();
};
// Game.cpp
#include "Game.h"

Game::Game(std::vector<Player*> players)
    : players(players),active_player(Game::players.begin())
{
    std::vector<Player*>::const_iterator player = Game::players.begin();
    std::vector<const Player*> proposers = { *player };
    for (unsigned int i = 0; i < 4; ++i) {
        ++player;
        if (player == Game::players.end()) player = Game::players.begin();
        proposers.push_back(*player);
    }

    Round round1(proposers);
    Game::rounds = { round1 };
}

void Game::next_round()
{
    Game::rounds.back().next_proposal();
}
#include <iostream>
#include "Game.h"

int main()
{
    Player playerA("A");
    Player playerB("B");
    Player playerC("C");
    Player playerD("D");
    Player playerE("E");
    Player playerF("F");

    std::vector<Player*> players = { &playerA,&playerB,&playerC,&playerD,&playerE,&playerF };
    Game game(players);

    for(unsigned int i = 0; i < 5; ++i) {
        game.next_round();
    }
}

出人意料的是,替换了两行代码

Round round1(proposers);
Game::rounds = { round1 };

Game.cpp

Round* round1 = new Round(proposers);
Game::rounds = { *round1 };

解决了这个问题,虽然我真的不明白为什么。毕竟,roundsGame 的成员变量,并且存在直到实例 game 被销毁。此 hack 的后续问题:最后一个代码片段中 round1 指向的实例是否被类 Game 的默认构造函数销毁,因为它在添加到成员变量之前被取消引用?

解决方法

您的 Round 无法正常复制:

class Round
{
private:
    std::vector<const Player*> proposers;
    std::vector<const Player*>::const_iterator proposer;
public:
    Round(std::vector<const Player*> proposers) : proposers(proposers),proposer(Round::proposers.begin()) {};

    void next_proposal() { (*Round::proposer)->make_proposal(); };
};

如果您确实复制了它,proposer 仍将是原始 Round 中元素的迭代器,而不是副本中的向量。当你这样做时:

Round* round1 = new Round(proposers);
Game::rounds = { *round1 };

然后本地对象 round1 在作用域结束时不会被销毁,因此在复制 {{1} 之后,现在位于 rounds 内部的迭代器}},指的是一个仍然活着的元素。虽然它指的是 round1 中的元素,而不是您放置在 round1 中的 Round

要么注意 rounds3/5 规则,要么使用索引而不是迭代器。复制整个向量时,索引不会失效。 (当您将更多元素推回向量时,它们也不会失效,但迭代器会)


类似问题的一个更简单的例子:

Round

#include <iostream> struct broken { int x; int* ptr; broken(int a = 0) : x(a),ptr(&x) {} }; int main() { broken a{42}; broken b{123}; a = b; a.x = 0; std::cout << *(a.ptr); } 复制到 b 后,a 中的指针仍将指向 a,因此输出为 b.x(不是 123 作为人们可能会期待)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res