第28课 友元的尴尬能力

1. 友元的概念

(1)友元C++中的一种关系友元关系发生在函数与类之间或类与类之间

(2)友元关系是单项的不能传递

class Point
{
    double x;
    double y;
    friend void func(Point& p);//声明func为Point类的友元函数
}

void func(Point& p){};//在这个函数中,可以访问Point类内的任何成员!

 

2. 友元的用法

(1)在类中以friend关键字声明友元

(2)类的友元可以是其它类或者具体函数

(3)友元不是类的一部分,也不受类中访问级别的限制,可以直接访问具体类的所有成员

(4)用友元注意事项

  ①友元关系不具备传递性

       

  ②类的友元可以是其它类的成员函数(即其它类的成员函数作为该类的友元函数

  ③类的友元可以是某个完整的类(即所有的成员函数都是友元

 

【编程实验】友元的使用初探   28-1.cpp

#include <stdio.h>

#include <math.h>

 

class Point
{

private:

    double x;

    double y;

 

public:

    Point(double x, double y)
    {

        this->x = x;

        this->y = y;

    }

 

    double getX(){return x;}

    double getY(){return y;}

 

    void getXY()

    {

        printf("x = %f, y = %f\n", x, y);

    }

 

    friend double Distance(Point& p1, Point& p2);

};

 

//从这里看,Distance只是一个普通的函数
double Distance(Point& p1, Point& p2)
{

     double ret = 0;

     ret=sqrt((p2.x-p1.x)*(p2.x-p1.x) +

              (p2.y-p1.y)*(p2.y-p1.y));//可以引用类中的私有成员!

     return ret;

}

int main()
{

    Point p1(1, 2);

    Point p2(10, 20);

 

    p1.getXY();

    p2.getXY();

 

    printf("|(p1, p2)| = %f\n", Distance(p1, p2));

 

    return 0;

}

运行结果:

 

 

3. 友元的尴尬

(1)友元为了兼顾C语言的高效而诞生的,但直接破坏面向对象的封装性

(2)友元在实际产品中的高效是得不偿失的在现代软件工程中己经逐渐被遗弃

 

【编程实验】友元的深入分析   28-2.cpp

#include <stdio.h>

 

class ClassC
{

private:

    const char* n;

 

public:

    ClassC(const char* n){this->n = n;}

   

    friend class ClassB; //B是C的友元类,即B可以任意访问C

};

 

class ClassB
{

private:

    const char* n;

 

public:

    ClassB(const char* n){this->n = n;}

 

    void getClassCName(ClassC& c)

    {

        printf("c.n = %s\n", c.n);//合法,因为在类C中,己将B声明为友元类

    }

    

    friend class ClassA;//A是B的友元类,即A可以任意访问B

};

 

 

class ClassA

{

private:

    const char* n;

 

public:

    ClassA(const char* n){this->n = n;}

 

    void getClassCName(ClassC& c)

    {

        //printf("c.n = %s\n", c.n);//非合法,因为在类C中,并没将A声明为友元类

    }

 

    void getClassBName(ClassB& b)

    {

        printf("b.n = %s\n", b.n);//合法,因为在类B中,己将A声明为友元类

    }

};

 

int main()
{

    //A是B的友元类,B是C的友元类,但A不能自动传递为C的友元类

    ClassA A("A");

    ClassB B("B");

    ClassC C("C");

 

    A.getClassBName(B);//A是B的友元类,

    B.getClassCName(C);//B是C的友元类

 

    return 0;

}

运行结果:

 

 

4. 小结

(1)友元是为了兼顾C语言的高效而诞生的

(2)友元直接破坏了面向对象的封装性

(3)友元关系不具备传递性

(4)类的友元可以是其它类的成员函数

(5)类的友元可以是某个完整的类

posted @ 2018-12-09 17:37  梦心之魂  阅读(123)  评论(0编辑  收藏  举报