C++中的函数不会改变对象属性

6

我完全不懂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;
}

我相信我的错误很明显,但我无法在任何地方找到答案。非常感谢您的帮助。


2
采用引用而非值传递参数。void pour(Container& a, Container& b) - Jarod42
2个回答

11

你正在将 Container 作为副本传递。这意味着在 pour 函数中更改的容器将在函数退出时被销毁。

解决方法是使用引用:

void pour(Container& a, Container& b)

类型后面的&表示引用。这意味着,在pour函数内部不使用ab的副本,而是可以访问调用者相同的ab


5

这可能是因为您正在按值传递对象。您需要通过引用传递它们。您可以通过更改方法头来实现这一点。

基本上,方法头中的每个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;
    }

};

我提到这两个因为在某些情况下,程序的设计者会采用所有引用都是const引用的约定。也就是说,通过引用传递的任何对象都不能被修改(这是通过在方法头中类型名称之前使用const关键字来强制执行的),而所有其他对象都通过指针传递。这使得在函数调用中更清楚,参数是否将被修改。

在该约定中使用const引用而不是按值传递的选择是为了提高函数调用的效率。传递引用比复制对象更快。


1
或者你可以只有const引用和非const引用,不需要麻烦地使用指针! - Charles
是的,但有些人抱怨他们希望能够仅从方法调用中了解情况。使用指针,方法调用基本上宣布它将进行更改。没有指针,方法调用表明该方法不会进行任何更改。 - Anish Goyal
1
有道理,但这正是文档的作用! - Charles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接