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

Phi*_*del 3 c++ oop

我对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)

我确定我的错误是显而易见的,但我无法在任何地方找到答案.任何帮助将不胜感激.

Cha*_*les 7

你把Containers作为副本传递.这意味着您在pour函数中更改的容器将在函数退出时被破坏.

解决方案是使用引用:

void pour(Container& a, Container& b)
Run Code Online (Sandbox Code Playgroud)

的&类型后表示参考.这意味着,该函数不是内部副本a和b内部副本,而是pour访问相同a和b调用者.


Ani*_*yal 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;
    }

};
Run Code Online (Sandbox Code Playgroud)

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

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