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

奥拉夫森

我正在尝试为纸牌游戏Avalon实现贝叶斯估计器。游戏共有五轮,每轮最多包含五个不同玩家提出的五个建议。如果提议被接受,则玩家继续执行任务,然后游戏进入下一轮。在上一轮比赛结束之前,尚不知道哪5名球员将在下一轮比赛中提议球队。我想跟踪当前使用迭代器向团队提出建议的玩家,但最终它指向无处。具体来说,在要求的构造函数中round1,迭代器Round::proposer正确指向&PlayerA的开始Round::proposers然而,当我这个实例(或它的?副本)添加到Game::rounds,那么团成员proposerGame::rounds.back()点无门,即使团成员proposers仍然是正确的。为什么会这样呢?在执行期间,当然会在call期间引发读取访问冲突异常(*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 };

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

maximum_prime_is_463035818

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销毁,因此,在复制之后,位于内部的迭代器引用仍在运行的元素。尽管它指的是内部的元素,但并不是您放置的元素roundsround1round1Roundrounds

要么注意3/5for的规则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);
}

复制ba指针后,ina仍将指向b.x,因此输出为123(不是0人们期望的那样)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在类模板的构造函数中初始化向量成员变量

来自分类Dev

如何在类定义中初始化向量成员变量?

来自分类Dev

静态const成员变量初始化

来自分类Dev

初始化const成员变量

来自分类Dev

C ++成员变量未初始化

来自分类Dev

如何初始化共享复杂初始化代码的多个常量成员变量?

来自分类Dev

如何初始化静态向量成员?

来自分类Dev

如何使用初始化列表来初始化2D向量成员?

来自分类Dev

成员变量默认初始化模板

来自分类Dev

初始化静态原子成员变量

来自分类Dev

初始化静态原子成员变量

来自分类Dev

成员变量元组的初始化

来自分类Dev

在循环中创建新对象时,将初始化未初始化的成员变量

来自分类Dev

访问变量成员

来自分类Dev

用指向自身的指针初始化成员变量

来自分类Dev

在模板化类中初始化私有成员变量向量

来自分类Dev

奇怪的未初始化const成员行为

来自分类Dev

使用其他静态常量成员初始化静态常量成员

来自分类Dev

为什么一个人可以初始化非常量和静态常量成员变量,却不能初始化静态成员变量?

来自分类Dev

使用文件输入中的值初始化类中的const成员变量

来自分类Dev

投放后未初始化变量

来自分类Dev

在类中常量成员的初始化

来自分类Dev

使用模板参数初始化静态常量成员

来自分类Dev

如何为类的内置类型成员变量获取/实现“未初始化的使用警告”消息?

来自分类Dev

Clang ++无法检测到未初始化的成员变量的使用

来自分类Dev

haxe未初始化的成员变量在平台之间不一致

来自分类Dev

如何为类的内置类型成员变量获取/实现“未初始化的使用警告”消息?

来自分类Dev

PHP常量成员变量

来自分类Dev

未显式初始化的全局并集变量的哪个成员将隐式初始化为0?

Related 相关文章

  1. 1

    如何在类模板的构造函数中初始化向量成员变量

  2. 2

    如何在类定义中初始化向量成员变量?

  3. 3

    静态const成员变量初始化

  4. 4

    初始化const成员变量

  5. 5

    C ++成员变量未初始化

  6. 6

    如何初始化共享复杂初始化代码的多个常量成员变量?

  7. 7

    如何初始化静态向量成员?

  8. 8

    如何使用初始化列表来初始化2D向量成员?

  9. 9

    成员变量默认初始化模板

  10. 10

    初始化静态原子成员变量

  11. 11

    初始化静态原子成员变量

  12. 12

    成员变量元组的初始化

  13. 13

    在循环中创建新对象时,将初始化未初始化的成员变量

  14. 14

    访问变量成员

  15. 15

    用指向自身的指针初始化成员变量

  16. 16

    在模板化类中初始化私有成员变量向量

  17. 17

    奇怪的未初始化const成员行为

  18. 18

    使用其他静态常量成员初始化静态常量成员

  19. 19

    为什么一个人可以初始化非常量和静态常量成员变量,却不能初始化静态成员变量?

  20. 20

    使用文件输入中的值初始化类中的const成员变量

  21. 21

    投放后未初始化变量

  22. 22

    在类中常量成员的初始化

  23. 23

    使用模板参数初始化静态常量成员

  24. 24

    如何为类的内置类型成员变量获取/实现“未初始化的使用警告”消息?

  25. 25

    Clang ++无法检测到未初始化的成员变量的使用

  26. 26

    haxe未初始化的成员变量在平台之间不一致

  27. 27

    如何为类的内置类型成员变量获取/实现“未初始化的使用警告”消息?

  28. 28

    PHP常量成员变量

  29. 29

    未显式初始化的全局并集变量的哪个成员将隐式初始化为0?

热门标签

归档