C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++友元

C++超详细讲解友元的使用

作者:清风自在 流水潺潺

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该类的友元函数

一、友元的概念

二、友元的用法

三、友元的语法

在类中用 friend 关键字对函数或类进行声明

先看一个不使用友元的代码:

#include <stdio.h>
#include <math.h>
class Point
{
    double x;
    double y;
public:
    Point(double x, double y)
    {
        this->x = x;
        this->y = y;
    }
    double getX()
    {
        return x;
    }
    double getY()
    {
        return y;
    }
    //friend double func(Point& p1, Point& p2);
};
double func(Point& p1, Point& p2)
{
    double ret = 0;
    ret = (p2.getY() - p1.getY()) * (p2.getY() - p1.getY()) +
          (p2.getX() - p1.getX()) * (p2.getX() - p1.getX());
    ret = sqrt(ret);
    return ret;
}
int main()
{
    Point p1(1, 2);
    Point p2(10, 20);
    printf("p1(%f, %f)\n", p1.getX(), p1.getY());
    printf("p2(%f, %f)\n", p2.getX(), p2.getY());
    printf("|(p1, p2)| = %f\n", func(p1, p2));
    return 0;
}

输出结果如下:

这个程序在x 和 y中计算两点之间的距离时需要频繁访问私有成员 x 和 y,所以不得不调用getX() 和getY() 来访问x 和 y,x 和 y 函数中调用了 8 次getX() 和getY(),很麻烦。

这个时候,就该我们的友元上场了:

#include <stdio.h>
#include <math.h>
class Point
{
    double x;
    double y;
public:
    Point(double x, double y)
    {
        this->x = x;
        this->y = y;
    }
    double getX()
    {
        return x;
    }
    double getY()
    {
        return y;
    }
    friend double func(Point& p1, Point& p2);
};
double func(Point& p1, Point& p2)
{
    double ret = 0;
    ret = (p2.y - p1.y) * (p2.y - p1.y) +
          (p2.x - p1.x) * (p2.x - p1.x);
    ret = sqrt(ret);
    return ret;
}
int main()
{
    Point p1(1, 2);
    Point p2(10, 20);
    printf("p1(%f, %f)\n", p1.getX(), p1.getY());
    printf("p2(%f, %f)\n", p2.getX(), p2.getY());
    printf("|(p1, p2)| = %f\n", func(p1, p2));
    return 0;
}

输出结果如下:

四、友元的尴尬

五、注意事项

下面来深入分析一下友元:

#include <stdio.h>
class ClassC
{
    const char* n;
public:
    ClassC(const char* n)
    {
        this->n = n;
    }
    friend class ClassB;
};
class ClassB
{
    const char* n;
public:
    ClassB(const char* n)
    {
        this->n = n;
    }
    void getClassCName(ClassC& c)
    {
        printf("c.n = %s\n", c.n);
    }
    friend class ClassA;
};
class ClassA
{
    const char* n;
public:
    ClassA(const char* n)
    {
        this->n = n;
    }
    void getClassBName(ClassB& b)
    {
        printf("b.n = %s\n", b.n);
    }
    /*
    void getClassCName(ClassC& c)
    {
        printf("c.n = %s\n", c.n);
    }
    */
};
int main()
{
    ClassA A("A");
    ClassB B("B");
    ClassC C("C");
    A.getClassBName(B);
    B.getClassCName(C);
    return 0;
}

B 是 C 的友元,A 是 B 的友元,输出结果如下:

既然 A 可以访问 B,B 可以访问 C,那么 A 可以访问 C 么?把上面代码取消注释:

  void getClassCName(ClassC& c)
  {
        printf("c.n = %s\n", c.n);
  }

输出报错,这说明友元关系不具备传递性

六、小结

到此这篇关于C++超详细讲解友元的使用的文章就介绍到这了,更多相关C++友元内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文