在main中调用类方法,更改不会在类方法之外持久化吗?

时间:2015-10-04 22:54:09

标签: c++ class vector methods setter

基本上,我有两个类,Peg和Disk。 (这是河内塔的一个程序)我的文件是Disk.h,Disk.cpp,Peg.h,Peg.cpp和main.cpp。不确定是否重要。这是Disk.h的磁盘类

#include <vector>
#include "gwindow.h"
#ifndef DISK_H
#define DISK_H

class Disk
{
private:
    int xCoord; //x and y coords are for drawing in a gwindow
    int yCoord;
    int mHeight;
    int mWidth;
    COLOR mColor;
    int mName;  //helps me keep track of which is which

public:
    Disk(); //default constructor
    Disk(int x, int y, int heightIn, int widthIn, COLOR colorIn);
    void setXY(int x, int y); //this is the one I'm having trouble with
    int getHeight();
    int getWidth();
    int getX();
    int getY();
    COLOR getColor();
    std::string diskColor();
    void draw(GWindow &gw);
    void nameDisk(int name);  //yet this one is working?
    int getName();
};

#endif

但是,我遇到了setXY函数的问题。当我从main调用它时,它会正确调用函数,更改setXY范围内的变量,但该值不会在函数外部持久存在。但是,nameDisk工作正常,基本上是一样的,除了它改变mName而不是xCoord和yCoord。这是setXY:

void Disk::setXY(int x, int y)
{
    xCoord = x;
    yCoord= y;
}

以下是我从main中调用它的方式:

pegVec[2].getDisks()[0].setXY(690, 200);

我知道这看起来很疯狂,但基本上pegVec是3个peg对象的向量。每个peg对象都有一个函数getDisks(),它返回当前peg上所有磁盘的向量。所以上面这一行试图在第一个peg on peg 2上执行setXY。抱歉,如果这个不清楚,但我已经尝试制作一个新的磁盘对象并在其上调用它,但这也不起作用。

这是getDisks,如果重要的话:

std::vector<Disk> Peg::getDisks()
{
    return disksOn;
}

和disksOn只是Peg的成员变量:

std::vector<Disk> disksOn;

我认为这可能是getDisks()如何工作的问题。我是一个菜鸟,但我猜测返回向量disksOn会对它进行“复制”,有点,这就是我用setXY函数改变的东西,但它与实际的disksOn向量相关联Peg对象?我不知道这是否合理。

到目前为止我尝试过:

  • 制作xCoord和yCoord公共变量并手动更新它们而不是制作setter函数。这没用。
  • 我在每一步都打印出x和y值。在setXY中,值已成功更新,但当函数结束时,它们又回到原来的状态。
  • 我尝试了一些关于const关键字的混乱,但我不理解它甚至无法让它运行。
  • 按引用/值传递所有内容
  • 在main中创建一个新函数,它接受磁盘向量作为输入,并使用getDisks作为该函数的输入。没有工作,同样的问题。
  • 测试了我的其他setter函数nameDisk,它运行正常。它与setXY基本相同,这就是为什么我认为问题出在getDisks上。
  • 在各个点(heh)使用指针,但我不确定最好的方法。我昨晚搞砸了,所以我不记得100%,但我想我试图让getDisks返回一个指针而不是向量,我认为这不起作用,但它更可能是我的语法问题和我是如何使用指针的。我认为这可行,但我不知道如何动摇它。

帮助?

2 个答案:

答案 0 :(得分:0)

你走在正确的轨道上 - 不知怎的,你正在寻找与你的想法不同的对象。使用引用是一个很好的解决方案,但你可能没有正确的解决方案; - )

尝试:

// Return reference to the disks on the peg.
std::vector<Disk>& Peg::getDisks()
{
    return disksOn;
}

答案 1 :(得分:0)

问题在于 std::vector<Disk> getDisks() { return disksOn; } 返回一个全新且独立的临时副本的disksOn,而不是对原始文件的引用。因此,您要修改一个在语句结束时被丢弃的临时副本。

你需要使用 std::vector<Disk> &getDisks() { return disksOn; },以便将引用返回给disksOn。

虽然如果要返回对vector成员对象的引用,你也可以将对象直接作为public访问,因为任何人都可以在这一点上操作向量并删除getDisks()函数,因为它没有服务访问保护方面的目的。

更好的设计是提供对单个磁盘的访问:

Disk &getDisk(int index) { 
  return disksOn[index]; 
}

const Disk &getDisk(int index) const { 
  return disksOn[index]; 
}

不直接访问向量背后的想法是,如果需要,您可以稍后更改基础容器类型,而无需更改Peg类之外的代码。

第二个版本(const)是访问const Peg对象的const磁盘所必需的。