欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C++深度解析】18、被遗弃的友元

程序员文章站 2024-03-21 16:24:16
...

1 友元

  • 友元发生在函数和类之间或者类与类之间
  • 友元不是类的一部分
  • 友元不受类中访问级别的限制,可以直接访问具体类的所有成员
  • 友元关系是单向的,不能传递

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

1.1 函数友元

当一个函数声明为类的友元时,就可以访问类中的所有成员。

编程实验:函数是类的友元

// 18-1.cpp
#include<stdio.h>
#include<math.h>
class Point
{
public:
    Point(int xx, int yy) : x(xx), y(yy){}
    double getX() { return x; }
    double getY() { return y; }
    friend double func(Point& p1, Point& p2);
private:
    double x, y;
};
double func(Point& p1, Point& p2)
{
    double ret = pow(p1.x-p2.x, 2) + pow(p1.y - p2.y, 2);
    ret = sqrt(ret);
    return ret;
}
int main()
{
    Point p1(1, 2);
    Point p2(4, 6);
    printf("p1(%f, %f)\n", p1.getX(), p1.getY());
    printf("p2(%f, %f)\n", p2.getX(), p2.getY());
    printf("%f\n", func(p1, p2));
    return 0;
}

函数 func() 是类的友元,可以访问类中的所有成员,可以直接访问类中的私有成员。

$ g++ 18-1.cpp -o 18-1
$ ./18-1
p1(1.000000, 2.000000)
p2(4.000000, 6.000000)
5.000000

1.2 类友元

当一个类 A 声明为另一个类 B 的友元时,就可以访问类 B 中的成员。

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

上面的代码中:
在类 B 中声明 friend class ClassA; 则 A 是 B 的友元;A可以访问 B 的成员。
在类 C 中声明 friend class ClassB;,则 B 是 C 的友元;B 可以访问 C 中的成员。

友元关系不具有传递行性,A 不是 C 的友元。

$ g++ 18-2.cpp -o 18-2
$ ./18-2
b.n = B
c.n = C

1.3 友元的缺点

友元直接破坏了面向对象的封装性,高效的同时得不偿失,已经逐渐被遗弃。

2 小结

1、类的友元可以是函数,也可以是类
2、友元不具备传递性
3、友元破坏了面向对象的封装性

相关标签: C++深度解析