我对c ++完全不熟悉,并认为编写一个解决了给定升难题的程序是个好习惯(你有2个容量为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;
}
Run Code Online (Sandbox Code Playgroud)
我确定我的错误是显而易见的,但我无法在任何地方找到答案.任何帮助将不胜感激.
你把Containers作为副本传递.这意味着您在pour函数中更改的容器将在函数退出时被破坏.
解决方案是使用引用:
void pour(Container& a, Container& b)
Run Code Online (Sandbox Code Playgroud)
的&类型后表示参考.这意味着,该函数不是内部副本a和b内部副本,而是pour访问相同a和b调用者.
这可能是因为您按值传递对象。您需要通过引用传递它们。您可以通过更改方法标头来做到这一点。
本质上,Container方法头中的每个实例都应该变成Container&. 呼叫不需要更改。
您还可以传递指针。然后您的参数将变为Container *a,并且在调用中您必须&在每个变量名称之前添加一个与号 ( ) (例如a变为&a)。然后,您还必须将对象的任何取消引用从句点 ( .) 更改为箭头 ( ->)。
你的方法将变成:
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;
}
};
Run Code Online (Sandbox Code Playgroud)
我提到这两者是因为在某些情况下,程序的设计者将采用所有引用都是 const 引用的约定。也就是说,任何通过引用传递的对象都不会被修改(这是通过在const方法头中的类型名称之前使用关键字来强制执行的),并且所有其他对象都通过指针传递。这使得在函数调用中是否会修改参数变得更加清楚。
在该约定中选择使用 const 引用而不是按值传递是为了提高函数调用的效率。传递引用比创建对象的副本更快。