函数不会改变c ++

时间:2017-03-20 23:33:10

标签: c++ oop

我对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;
}

我确定我的错误很明显但我无法在任何地方找到答案。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:5)

您将<Field>作为副本传递。这意味着您在component函数中更改的容器将在函数退出时被破坏。

解决方案是使用引用:

Container

类型后面的pour表示引用。这意味着,该函数不会在void pour(Container& a, Container& b) 内使用&a的副本,而是可以访问与调用者相同的bpour

答案 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的选择是提高函数调用的效率。传递引用比制作对象的副本更快。