修改对象与修改该对象的副本

时间:2012-08-31 15:44:31

标签: c++ object

我试图尽可能地解决我的问题,但它涉及在C ++中定义的多个对象。虽然它们很简单 - 如果我在进一步解释之前分享我的代码,我认为最好:

#include <iostream>
#include <vector>

struct Cell {
        bool visited;
        Cell():visited(false) {}
        void setVisited(bool val) {visited = val;}
        bool beenVisited() {return visited;}
};
struct Vector2D
{
        int size;
        std::vector<Cell> myVector;
        Vector2D(int n): size(n), myVector(n*n) {}
        Cell& getAt(int x, int y) {return myVector[((x * size) +y)];}
};

int main()
{
    Vector2D vec = Vector2D(1);
    Cell cell= vec.getAt(0,0);

    cell.setVisited(true);
    cell = vec.getAt(0,0);
    if (cell.beenVisited() == false)
        std::cout << "Why is this not true like I set it a moment ago?\n";
}

我真诚地为所有这一切道歉,但需要说明问题。正如您所看到的,我得到了我认为是Cell对象,将其访问过的实例数据设置为true,然后切换到另一个单元格。那么,为什么当我回到同一个单元格时,发现被访问的值是假的而不是真的?!这就像它没有注册我的私人数据变化!

这样做的最佳方式是什么?

由于

2 个答案:

答案 0 :(得分:3)

Cell cell= vec.getAt(0,1);

对象的副本。 使用

Cell& cell = vec.getAt(0, 1);

或只是

vec.getAt(0, 1).setVisited(true);

修改

此代码应该有效。

using namespace bob;
Vector2D vec = Vector2D(5);
vec.setAt(0,0, Cell(0,0));
vec.setAt(0,1, Cell(0,1));
vec.setAt(0,2, Cell(0,2));
Cell& cell= vec.getAt(0,1);

cell.setVisited(true);
Cell cell1 = vec.getAt(0,2);
cell1 = vec.getAt(0,1);
if (cell1.beenVisited() == false)
{
    std::cout << "Why is this not true like I set it a moment ago?" << std::endl;
}

http://liveworkspace.org/code/53634eda052a07885d4e6c062a0fd302

答案 1 :(得分:0)

ForEveR的答案是正确的 - 您需要将getAt()返回的值存储在引用变量中,而不是将其复制到值变量中。

您可能会考虑明确声明永远不应复制“Cell”类,这将帮助您更快地捕获此类错误。这可以通过声明私有拷贝构造函数(没有正文)来完成;或者如果你正在使用boost,那么可以通过继承基类“boost :: noncopyable”(docs for noncopyable)来完成。