主类中调用的类方法,更改不会在类方法外持久?
基本上,我有两个类,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;
}
,这里是我如何把它从主:
pegVec[2].getDisks()[0].setXY(690, 200);
我知道这看起来疯狂,但基本上pegVec是3个挂钩对象的载体。每个挂钩对象都有一个函数getDisks(),该函数返回当前挂钩上所有磁盘的矢量。因此,上面的行试图在第2个挂钩上执行setXY。对不起,如果这不清楚,但我已经尝试制作一个新的磁盘对象并在其上调用它,那也不起作用。
这里是getDisks,如果它的问题:
std::vector<Disk> Peg::getDisks()
{
return disksOn;
}
和disksOn只是钉的成员变量:
std::vector<Disk> disksOn;
我认为这可能是与如何getDisks问题()的作品。我是一个noob,但我猜测,返回矢量disksOn使它的“副本”,这是我改变了我的setXY功能,但它不是相同的实际disksOn矢量相关Peg对象?我不知道这是否合理。
我试过到目前为止:
- 制作XCOORD和YCOORD公共变量和更新它们手动,而不是使一个setter函数。这没有奏效。
- 我在每一步打印出x和y值。在setXY中,值已成功更新,但是当函数结束时,他们又回到了原来的样子。
- 我尝试了一些与const关键字混乱,但我不明白它,甚至无法让它运行。
- 通过引用/值传递所有内容
- 在接受Disk矢量作为输入并使用getDisks作为该函数的输入的main中创建一个新函数。没有工作,同样的问题。
- 测试了我的另一个setter函数nameDisk,它工作正常。它基本上与setXY相同,这就是为什么我认为问题出在getDisks上。
- 始终在各个点(heh)使用指针,但我不确定这是否是最佳方式。我昨晚搞砸了,所以我不记得100%,但我想我试图让getDisks返回一个指针,而不是矢量,我认为它没有问题,但它更可能是我的语法问题和我如何使用指针。我认为这可能有效,但我不知道如何动摇它。
帮助?
你是在正确的轨道上 - 不知何故,你正在看的不同于你自己认为的物体。使用引用是一个很好的解决方案,但你可能没有得到正确的;-)
尝试:
// Return reference to the disks on the peg.
std::vector<Disk>& Peg::getDisks()
{
return disksOn;
}
的问题是, std::vector<Disk> getDisks() { return disksOn; }
返回一个完全新的独立临时副本 disksOn而不是对原始的引用。所以你正在修改一个在声明结尾被丢弃的临时副本。
你需要为了返回参考到disksOn使用 std::vector<Disk> &getDisks() { return disksOn; }
。
虽然如果您要返回对矢量成员对象的引用,那么您可能会将对象直接作为公共对象访问,因为任何人都可以在此处操作矢量,并在服务时摆脱getDisks()函数在访问保护方面没有任何目的。
更好的设计是给访问单个磁盘:
Disk &getDisk(int index) {
return disksOn[index];
}
const Disk &getDisk(int index) const {
return disksOn[index];
}
背后不给人以矢量直接访问我们的想法是,如果需要在不改变外部的代码,你可以稍后更改基础容器类型Peg类。
第二个版本(const)对于访问const Peg对象的const Disks是必需的。
感谢您的回答。你能解释一下const Disk对象和普通Disk对象之间的区别吗? const Disk对象是不可变的吗? –
简单地说:是的。 A ** const **对象是一个不能直接更改的对象,只能调用它的const成员函数。然而,它可以通过对同一对象使用不同的非const指针或非const引用来改变,并且某些函数可能会通过执行必要的const_cast ()来改变它,例如,用于实现**引用计数对象**作为引用计数需要更新,即使该对象在概念上被认为是常量。所以要迂腐,它不是一成不变的。 –
例如'int a = 5; const int&const_ref_a = a; cout
嗯,工作!非常感谢。我记得昨天晚上试了一下,但是我让事情变得更加复杂。 –