【问题标题】:function doesn't change object attributes in c++函数不会更改 C++ 中的对象属性
【发布时间】:2017-03-20 23:33:09
【问题描述】:

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

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

【问题讨论】:

  • 通过引用而不是按值获取参数。 void pour(Container&amp; a, Container&amp; b)

标签: c++ oop


【解决方案1】:

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

解决方案是使用引用:

void pour(Container& a, Container& b)

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

【讨论】:

    【解决方案2】:

    这可能是因为您按值传递对象。您将希望通过引用传递它们。你可以通过改变你的方法头来做到这一点。

    基本上,方法头中Container 的每个实例都应该变成Container&amp;。呼叫不需要更改。

    您也可以传递指针。然后,您的参数将变为 Container *a,并且在您的调用中,您必须在每个变量名称之前添加一个与号 (&amp;)(例如,a 变为 &amp;a)。然后,您还必须将对象的任何 derefs 从句点 (.) 更改为箭头 (-&gt;)。

    你的方法会变成:

    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 引用而不是按值传递是为了提高函数调用的效率。传递引用比复制对象要快。

    【讨论】:

    • 或者您可以只拥有const 引用和非const 引用,而不必乱用指针!
    • 没错,但有些人抱怨他们希望能够仅从方法调用中分辨出来。使用指针,方法调用基本上宣布它将进行更改。如果没有,方法调用表明该方法不会进行任何更改。
    • 有道理,但这文档的用途!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 2016-01-07
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多