C++入门到放弃(09)——友元:friend

发布时间 2023-08-06 20:46:35作者: 无夜千幕雪

1.基本用法

友元的概念还是比较简单的,主要作用是,让声明的友元函数或者友元类,可以直接访问当前类的私有成员。

可以这样理解,友元声明代表了,向大家说明这个函数或类是我的朋友(friend),因此它可以随意使用我内部的私有成员。

基本形式:

friend+函数声明

friend+class+类名

class Point {
    friend double Distance(const Point& p1, const Point& p2);    //友元函数
    friend class Line;        //友元类
private:
    int m_x;
    int m_y;
};

2.友元函数

基本形式:

class Point {
    friend double Distance(const Point& p1, const Point& p2);
private:
    int m_x;
    int m_y;
};
double Distance(const Point& p1, const Point& p2) {
    double derta_x = p1.m_x - p2.m_x;
    double derta_y = p1.m_y - p2.m_y;
    return sqrt(derta_x * derta_x - derta_y * derta_y);
}

声明之后,就可以在函数Distance中调用Point的私有成员。需要保证友元函数与当前类在同一命名空间下。

注意,以下示例为错误,不能这么用!!!

1.友元函数声明不能跨命名空间

namespace space1 {
    class Point {
        friend double Distance(const Point& p1, const Point& p2);
        friend double space2::Distance(const Point& p1, const Point& p2);    //无效
}
namespace space2 {
    double Distance(const space1::Point& p1, const space1::Point& p2) {
        double derta_x = p1.m_x - p2.m_x;    //错误,无法调用私有成员
        double derta_y = p1.m_y - p2.m_y;    //错误,无法调用私有成员
        return sqrt(derta_x * derta_x - derta_y * derta_y);
    }
}

2.友元函数声明不能针对类当中的函数(除非声明友元类)

class Point {
    friend double Line::Distance();    //无效
private:
    int m_x;
    int m_y;
};
class Line {
private:
    double Distance();
    Point m_p1;
    Point m_p2;
};
double Line::Distance() {
    double derta_x = m_p1.m_x - m_p2.m_x;    //错误,无法调用私有成员
    double derta_y = m_p1.m_y - m_p2.m_y;    //错误,无法调用私有成员
    return sqrt(derta_x * derta_x - derta_y * derta_y);    
}

3.友元类

基本形式:

class Point {
    friend class Line;
private:
    int m_x;
    int m_y;
};
class Line {
private:
    double Distance();
    Point m_p1;
    Point m_p2;
};
double Line::Distance() {
    double derta_x = m_p1.m_x - m_p2.m_x;
    double derta_y = m_p1.m_y - m_p2.m_y;
    return sqrt(derta_x * derta_x - derta_y * derta_y);
}

声明之后,就可以在类Line中调用Point的私有成员。需要保证友元类与当前类在同一命名空间下。和友元函数相同,不同命名空间,或者类中类的情况,友元声明无效。

注意,以下示例为错误,不能这么用!!!

1.友元类声明不能跨命名空间

namespace space1 {
    class Point {
        friend class space2::Line;    //无效
    private:
        int m_x;
        int m_y;
    };
}
namespace space2 {
    class Line {
    private:
        double Distance();
        space1::Point m_p1;
        space1::Point m_p2;
    };
    double Line::Distance() {
        double derta_x = m_p1.m_x - m_p2.m_x;    //错误,无法调用私有成员
        double derta_y = m_p1.m_y - m_p2.m_y;    //错误,无法调用私有成员
        return sqrt(derta_x * derta_x - derta_y * derta_y);    
    }
}

2.友元类声明不能针对类中类

class Point {
    friend class Plane::Line;    //无效
private:
    int m_x;
    int m_y;
};
class Plane {
private:
    class Line {
        double Distance();
        Point m_p1;
        Point m_p2;
    };
};
double Plane::Line::Distance() {
    double derta_x = m_p1.m_x - m_p2.m_x;    //错误,无法调用私有成员
    double derta_y = m_p1.m_y - m_p2.m_y;    //错误,无法调用私有成员
    return sqrt(derta_x * derta_x - derta_y * derta_y);
}