Loading

友元

1.为什么需要友元函数

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

class Wealth {
private:
    long gold;
    long silver;
    long copper;
public:
    Wealth(long gold, long silver, long copper)
    {
        this->gold = gold;
        this->silver = silver;
        this->copper = copper;
    }
    //重载+运算符,将两份财产相加
    Wealth operator+ (Wealth& wealth) const
    {
        long copperTotal = this->copper + wealth.copper;
        long silverTotal = this->silver + wealth.silver;
        long goldTotal = this->gold + wealth.gold;
        return Wealth(goldTotal+silverTotal/100, (silverTotal+copperTotal/100)%100, copperTotal%100);
    }
    //重载+运算符,将财产加上一个铜币数
    Wealth operator+(long copper)
    {
        long copperTotal = this->copper + copper;
        return Wealth(this->gold + (this->copper + copperTotal / 100) / 100, (this->copper + copperTotal / 100) % 100, copperTotal % 100);
    }

    string toString()
    {
        return "you have: " + to_string(this->gold) + " golds, " + to_string(this->silver) + " silvers and " + to_string(this->copper) + " coppers";
    }
};

int main(void)
{
    Wealth w1(10, 10, 10);
    Wealth w2(90, 90, 90);
    Wealth w = w1 + w2;
    cout << w.toString() << endl;
    w = w + 1;
    //w = 1 + w; //没有与这些操作数匹配的 + 运算符
    cout << w.toString() << endl;
    cin.get();
    return 0;
}

 

上面的代码中, w = w + 1是可以通过编译的,但是 w = 1 + w 不行,这样一个类提供出去显然不行。

w = w + 1可以,是因为operator+是类的成员函数,所以w = w + 1实际上是 w = w.operator+(1),所以w = 1 + w 编译不过也可以理解了,因为 1 这个int里面没有operator+这个函数

解决这样的问题,就需要友元函数出马,代码如下,将此函数加入Wealth类

//友元函数,重载+运算符,将财产加上一个铜币数
//虽然operator+是在Wealth类里定义的,但却不是Wealth的成员函数,也不能使用wealth.operator+来调用
//编译能够将1+wealth与operator+(1,wealth)匹配起来
friend Wealth operator+(long copper, Wealth &wealth)
{
    long copperTotal = wealth.copper + copper;
    return Wealth(wealth.gold + (wealth.copper + copperTotal / 100) / 100, (wealth.copper + copperTotal / 100) % 100, copperTotal % 100);
}

 

2.还有哪种情况必须要使用友元函数

如果想要使用 cout << wealth 来打到wealth.display()的效果该怎么办呢,cout << 之所以能支持许多不同基本类型的输出,是因为ostream类里面对<<进行了许多重载以支持这些类型。但是显然我们不能修改ostream类,而只能是让Wealth类知道如何使用cout。

显然这也需要使用友元函数,为什么?因为我们需要的效果是cout << wealth,如果使用一个成员函数来重载 << ,Wealth对象将是第一个操作数,这意味着必须像下面这样使用<<:

  wealth << cout

这会让人困惑,但是友元函数就不同了,很OK了,因为它可以这样

void operator<< (ostream& os, const Wealth& wealth)

{

  os << 略

}

具体见下面的示例代码

 

posted @ 2018-07-16 01:11  注销111  阅读(121)  评论(0编辑  收藏  举报