码迷,mamicode.com
首页 > 编程语言 > 详细

C++语言学习(七)——友元

时间:2018-07-15 19:28:15      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:引用   提高   c++语言学习   ble   argc   通信   访问   友元类   继承   

C++语言学习(七)——友元

一、友元简介

1、友元简介

面向对象编程的类的设计机制实现了数据的隐藏与封装,类的成员变量一般定义为私有成员,成员函数一般定义为公有的,是类与外部的通信接口。在实践中,类外的某些函数需要频繁地访问类的成员变量,可以将类外的函数定义为类的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但友元破坏了类的封装性和隐藏性,使得非类的成员函数可以访问类的私有成员。
友元是C++语言中的一种关系,友元关系发生在函数与类之间或者类与类之间。友元关系是单向的,不能传递。
与类有友元关系的函数称为友元函数,与类有友元关系的类称为友元类。

2、友元的特性

友元的特性如下:
A、在类中以friend关键字声明友元
B、类的友元可以是其它类或具体函数
C、友元不是类的一部分
D、友元不受类中访问级别的限制
E、友元可以直接访问具体类的所有成员
F、友元关系不能被继承
G、友元关系是单向的,不具交换性
H、友元关系不具有传递性

3、友元的本质

友元的本质,是让其它不属于本类的成员(全局函数,其它类的成员函数,其它类),成为本类的成员而具备本类成员的属性。

二、友元函数

1、友元函数简介

友元函数是可以直接访问类的私有成员的非成员函数,是定义在类外的函数,可以是不属于任何类的全局函数或是其它类的成员函数,但需要在类的定义中加以声明。

2、全局函数为友元函数

全局函数作为类的友元声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 函数名(形式参数);
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

#include <iostream>
#include <cmath>

using namespace std;

class Point
{
public:
    Point(double x = 0, double y = 0)
    {
        this->x = x;
        this->y = y;
    }
    void printPoint()
    {
        cout << "(" << x << "," << y << ")";
    }
    //友元函数声明
    friend double getDistance(const Point &a, const Point &b);
private:
    double x;
    double y;
};

double getDistance(const Point &a, const Point &b)
{
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx*dx + dy*dy);
}

int main(int argc, char *argv[])
{
    Point a(0,0);
    Point b(1,8);
    cout << "Point";
    a.printPoint();
    cout << " and Point";
    b.printPoint();
    cout << " has distance at "<< getDistance(a, b) << endl;
    return 0;
}

3、类成员函数为友元函数

类成员函数作为类的友元声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 类名::函数名(形式参数);
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

#include <iostream>
#include <cmath>

using namespace std;

class Point;

class ManagerPoint
{
public:
    double getDistance(const Point &a, const Point &b);
};

class Point
{
public:
    Point(double x = 0, double y = 0)
    {
        this->x = x;
        this->y = y;
    }
    void printPoint()
    {
        cout << "(" << x << "," << y << ")";
    }
    //友元函数声明
    friend double ManagerPoint::getDistance(const Point &a, const Point &b);
private:
    double x;
    double y;
};

double ManagerPoint::getDistance(const Point &a, const Point &b)
{
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx*dx + dy*dy);
}

int main(int argc, char *argv[])
{
    ManagerPoint manager;
    Point a(0,0);
    Point b(1,8);
    cout << "Point";
    a.printPoint();
    cout << " and Point";
    b.printPoint();
    cout << " has distance at "<< manager.getDistance(a, b) << endl;
    return 0;
}

上述代码中使用了类的前向声明。前向声明,是一种不完全型(forward declaration)声明,即只需提供类名(无需提供类实现)即可。前向声明功能有限:
A、不能定义类的对象。
B、可以用于定义指向这个类型的指针或引用。
C、用于声明(不是定义)使用该类型作为形参或者返回类型的函数。

三、友元类

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以访问另一个类的私有成员、保护成员时,可以将该类声明为另一类的友元类。
定义友元类的语句格式如下:
friend class 类名;
friend和class是关键字,类名必须是程序中的一个已定义的类。

#include <iostream>
#include <cmath>

using namespace std;

class Point;

class ManagerPoint
{
public:
    double getDistance(const Point &a, const Point &b);
};

class Point
{
public:
    Point(double x = 0, double y = 0)
    {
        this->x = x;
        this->y = y;
    }
    void printPoint()
    {
        cout << "(" << x << "," << y << ")";
    }
    //友元类声明
    friend class ManagerPoint;
private:
    double x;
    double y;
};

double ManagerPoint::getDistance(const Point &a, const Point &b)
{
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx*dx + dy*dy);
}

int main(int argc, char *argv[])
{
    ManagerPoint manager;
    Point a(0,0);
    Point b(1,8);
    cout << "Point";
    a.printPoint();
    cout << " and Point";
    b.printPoint();
    cout << " has distance at "<< manager.getDistance(a, b) << endl;
    return 0;
}
ManagerPoint类的所有成员函数都是类Point的友元函数,能访问类Point的私有成员和保护成员。

C++语言学习(七)——友元

标签:引用   提高   c++语言学习   ble   argc   通信   访问   友元类   继承   

原文地址:http://blog.51cto.com/9291927/2143190

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!