c++ - 为什么在有私有(private)变量的情况下需要使引用常量?

标签 c++ c++11 operator-overloading

这是来自 http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/ 的一些代码

我一直在通过几个自学网站和浏览论坛研究运算符重载。我问了一个关于使用不同方法重载的问题,我现在明白了。该问答链接在这里 How is this returning a value when it has not been defined?

不过,这个方法跟引用我不太懂。我尝试过使用不同的方法来实现代码,并且发现有些方法不太复杂。

我理解的方法是创建一个类的实例作为运算符函数的参数,运算符函数内的一个临时实例,并使用 = 运算符返回这些值。这种方式要复杂得多,我有几个问题,为什么它能奏效。

问题的措辞是在您阅读代码时提出的,但这是我提出的三个问题。
(问题1)Ceteris parabis,为什么参数中需要const关键字?我知道如果我将变量公开我不会,但为什么如果有友元类,或者如果代码是在类本身内部编写的,我是否需要使用 const。
(问题2)如果我把friend函数放在类里面,为什么还需要关键字“friend”?
(问题3)类c1、c2在哪里初始化的?它们有一个引用,但是在返回之前没有初始化,但是在引用下面。我认为编译时会出错。

class Cents
{
private:
    int m_nCents;

public:
    Cents(int nCents) { m_nCents = nCents; }
    //I know this assigns each
    //instance to the private variable m_nCents since it's private.

    // Add Cents + Cents 
    friend Cents operator+(const Cents &c1, const Cents &c2); 

    //why do we need
    //to make this a friend? why can't we just put it inside the class and not  
    //use the "friend" keyword? also why do I need to make the variables public
    //if i remove const from the parameters

    int GetCents() { return m_nCents; } 
    //I know how this is used to return the
    // variable stored in m_nCents, in this program it is for cout
};

// note: this function is not a member function!
Cents operator+(const Cents &c1, const Cents &c2)
//where are these references 
//actually defined? I do not see c1 or c2 anywhere except in the return, but
//that is below the code that is referencing the class
{
    // use the Cents constructor and operator+(int, int)
    return Cents(c1.m_nCents + c2.m_nCents);
}

int main()
{
    Cents cCents1(6);
    Cents cCents2(8);
    Cents cCentsSum = cCents1 + cCents2;
    std::cout << "I have " << cCentsSum .GetCents() << " cents." << std::endl;

    return 0;
}

最佳答案

也许下面的更能说明问题:当你计算总和时,你的代码相当于:

Cents cCentsSum = operator+(cCents1,cCents2);

(是的,以上也是实际的法律代码)。

这更类似于函数调用,实际上是运算符。引用是参数,因此 const Cents& c1 引用 cCents1const Cents& c2 引用 cCents2

现在需要实现这个免费功能,但是您访问的是c1.m_cents,它是private。为了允许这样做,您需要将该方法声明为 friend,否则您编写的自由函数将产生访问错误。

仍然需要将它声明为 friend ,即使您将它放在类中也是如此,因为运算符是特殊的。编译器看到您的运算符 + 有两个参数,因此它知道这不是成员函数。它实际上相当于free函数的代码,只是更加简洁。

最后,您希望这些引用是 const 以避免意外修改。考虑一下你是否写:

Cents operator+(Cents &c1, Cents &c2)
{
    return Cents(c1.m_nCents += c2.m_nCents);
}

注意 += 而不是 +,它会修改 c1 的值。在您的示例中,这意味着您调用

Cents cCentsSum = cCents1+cCents2;

cCents1 的值将被修改。当然不可取。通过使参数常量引用,您要求编译器确保上述情况不会发生,并在编译代码时报告为错误。

关于c++ - 为什么在有私有(private)变量的情况下需要使引用常量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19257215/

相关文章:

c++ - 当新大小小于当前大小时,std::vector::resize() 是否会重新分配?

C++避免代码重复运算符重载

c++ - dylib 中的重载运算符删除替换了 OSX 中的系统运算符

c++ - 在成员函数上使用 CreateThread 的问题

c# - 当我使用 regasm 时,所有参数都输入为输入?那可以改变吗?

c++11 - 在 C++ 中将 NULL 转换为 SomeType* 有什么用?

C++ 标准库可移植性

c++ - 允许将类分配为零

c++ - C\C++ 中的 Linux 无线 API

c++ - 在 CentOS 7 上从源代码构建 TileServer GL