我对c ++完全陌生,并认为编写一个解决了一个特定升难题的程序是个好习惯(你有两个容量为3升和5升的容器,你能获得4升吗?等等)
我为一个给定的容器编写了一个类,并且该函数旨在用于“倾倒”。一个容器的内容到另一个容器。尽管整个类都是公共的,但该函数并没有改变任何对象内容的值。我不确定我做错了什么。
这是我的代码:
#include <iostream>
using namespace std;
class Container {
public:
int quantity; //quantity of water in container
int size; //max amt of water
};
void pour(Container a, Container b) {
int differential = b.size - b.quantity;
if (a.quantity <= differential) {
b.quantity = a.quantity + b.quantity;
a.quantity = 0;
}
else if (a.quantity > differential) {
b.quantity = b.quantity - differential;
a.quantity = a.quantity - differential;
}
};
int main() {
Container bottle1;
bottle1.quantity = 5;
bottle1.size = 6;
Container bottle2;
bottle2.quantity = 0;
bottle2.size = 2;
pour(bottle2, bottle1);
cout << bottle1.quantity << ", " << bottle2.quantity << endl;
return 0;
}
我确定我的错误很明显但我无法在任何地方找到答案。任何帮助将不胜感激。
答案 0 :(得分:5)
您将<Field>
作为副本传递。这意味着您在component
函数中更改的容器将在函数退出时被破坏。
解决方案是使用引用:
Container
类型后面的pour
表示引用。这意味着,该函数不会在void pour(Container& a, Container& b)
内使用&
和a
的副本,而是可以访问与调用者相同的b
和pour
。
答案 1 :(得分:3)
这可能是因为您按值传递对象。你想通过引用传递它们。您可以通过更改方法标题来完成此操作。
基本上,方法标题中的每个Container
实例都应该变为Container&
。呼叫不需要更改。
您也可以传递指针。然后,您的参数将变为Container *a
,并且在您的通话中,您必须在每个变量名称之前添加&符号(&
)(例如a
变为&a
)。然后,您还必须将对象的任何derefs从句点(.
)更改为箭头(->
)。
您的方法将成为:
void pour(Container *a, Container *b) {
int differential = b->size - b->quantity;
if (a->quantity <= differential) {
b->quantity = a->quantity + b->quantity;
a->quantity = 0;
}
else if (a->quantity > differential) {
b->quantity = b->quantity - differential;
a->quantity = a->quantity - differential;
}
};
我提到了两者,因为在某些情况下,程序的设计者将采用所有引用都是const引用的约定。也就是说,不会修改通过引用传递的任何对象(通过在方法头中的类型名称之前使用const
关键字来强制执行),并且所有其他对象都通过指针传递。这使得在函数调用中更清楚是否将修改参数。
在该约定中使用const引用而不是pass-by-value的选择是提高函数调用的效率。传递引用比制作对象的副本更快。