C++ 友元

为什么使用友元?

例如:求两点之间的距离

#include <iostream>
#include <cmath>
class Point      //Point类声明
{
public:    //外部接口
    Point(int x=0, int y=0) : x(x), y(y) { }
    int getX()
    {
        return x;
    }
    int getY()
    {
        return y;
    }
private:    //私有数据成员
    int x, y;
};
float dist( Point& a, Point& b)
{
    double x = a.getX() - b.getX();
    double y = a.getY() - b.getY();
    return static_cast<float>(sqrt(x * x + y * y));
}
解决方法:设计一个函数计算两点间的距离,解决方案普通函数,成员函数和类的组合都不好,最好采用友元关系。
 

友元

面向对象程序设计主张程序的封装、数据的隐藏,不过任何事物都不是绝对的,友元打破了这种封装和隐藏。
友元关系提供了一种共享机制,实现不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享。
通俗点举个例子,一个家庭需要通过防盗门窗、门锁、保险柜等措施不让外人接触,但在一些特殊情况下,例如全家出游,又需要检查煤气、水电情况,就不得不把钥匙交给值得依赖的朋友,而这位朋友就是友元。
通过友元关系,一个普通函数或者类的成员函数可以访问封装于另外一个类的数据。
 
同时也要明白,友元是C++提供的一种破坏数据封装和数据隐藏的机制。便于实现数据共享,提高程序的效率和可读性。
为了确保数据的完整性及数据封装与隐藏的原则,建议尽量不使用或少使用友元。
 
在一个类中,可以利用关键字 friend将其他函数或类声明为友元。可以使用友元函数和友元类。
 

友元函数

 如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的私有成员和受保护成员。
 
作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。
访问对象中的成员必须通过对象名。
UML中由关键字friend修饰。
#include <iostream>
#include <cmath>
class Point      //Point类声明
{
public:    //外部接口
    Point(int x=0, int y=0) : x(x), y(y) { }
    int getX()
    {
        return x;
    }
    int getY()
    {
        return y;
    }
    friend float dist(Point &a, Point &b);
private:    //私有数据成员
    int x, y;
};
float dist( Point& a, Point& b)
{
    double x = a.x - b.x;
    double y = a.y - b.y;
    return static_cast<float>(sqrt(x * x + y * y));
}
int main()
{
    Point p1(1, 1), p2(4, 5);
    cout <<"The distance is: ";
    cout << dist(p1, p2) << endl;
    return 0;
}

 

 

友元类

 
不仅可以将一个函数声明为一个类的“朋友”,而且可以将一个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。
在A类的定义体中用以下语句声明B类为其友元类:friend B;
声明友元类的一般形式为:
friend 类名;
友元类之间的关系不能传递,不能继承。友元的关系是单向的而不是双向的。进行函数重载时,需要将重载函数集中每一个希望设为友元的函数都声明为友元。
 
class A
{
    friend class B;
public:
    void display()
    {
        cout << x << endl;
    }
private:
    int x;
}
class B
{
public:
    void set(int i);
    void display();
private:
    A a;
};

void B::set(int i)
{
    a.x=i;
}
void B::display()
{
    a.display();
}

 

 
posted @ 2019-05-02 11:38 王陸 阅读(...) 评论(...) 编辑 收藏