首页 > 编程语言 >C++入门到放弃(09)——友元:friend

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

时间:2023-08-06 20:57:07浏览次数:29  
标签:友元 p2 p1 Point derta 09 C++ double class

​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);
}


标签:友元,p2,p1,Point,derta,09,C++,double,class
From: https://www.cnblogs.com/wyqmx/p/17610003.html

相关文章

  • 【VSCode】mac系统利用VSCode配置C++环境
    https://blog.csdn.net/bsy1111/article/details/131056647在官网上看到VSformac不能建C++项目,找到一个教程用VSCode配置一下C++环境可以跑点简单的代码应付一下日常使用,要是有大佬知道怎么在mac上用VisualStudio写C++的话还麻烦不吝赐教......
  • C++动态规划经典试题解析之打家劫舍系列
    1.前言力扣上有几道与打家劫舍相关的题目,算是学习动态规划时常被提及的经典试题,很有代表性,常在因内大大小小的社区内看到众人对此类问题的讨论。学习最好的方式便是归纳总结、借鉴消化,基于这个目的,本文对此类问题也做了讲解,在一些优秀思想的基础上添加了个人观点。闲话少说,进入......
  • 最低通行费C++
    题目描述】一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。这个商人期望在规定时间内用最少......
  • 怪盗基德的滑翔翼C++
    题目描述】怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为目标的超级盗窃犯。而他最为突出的地方,就是他每次都能逃脱中村警部的重重围堵,而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼。有一天,怪盗基德像往常一样偷走了一颗珍贵的钻石,不料却被柯南小朋友识破了伪装,而他的......
  • 【JavaScript09】模板字符串(Template Strings)
    前言JavaScript在ES6新增了模板字符串(TemplateStrings)语法,其作用是可以在字符串中换行,以及将变量和表达式插入字符串。模板字符串模板字面量使用反引号(``)而不是单引号('')或双引号("")来定义字符串示例:letuser="xwl";letage=20;letx=`myname......
  • Day_09 字典类型
    1.字典的定义: 2.字典数据类型转换: 3.字典数据类型转换_2: 4.字典的内置方法: 5.字典的len方法和成员运算in和notin: 6.字典的删除del,pop,popitem: 7.键keys(),值values(),键值对items(): 8.字典需要掌握的方法: ......
  • 09 简易计算器,回顾组合与内部类
    oop原则:组合大于继承继承:classAextendsB{}组合:classA{publicBb}由面向过程逐步转变为面向对象对象.方法packageGUI;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;/*oop原则:组合大于继承继承:classAextendsB......
  • C++中BigEden、SmallEden编码
    基本概念大端小端表示,一个数字在内存中或硬盘上记录时,是高位在前或在后,高位在前就是大端(BigEden),在后就是小端(samllEden)。我们日常记录和代码里定义一千二百三四如:inta=1234;就是大端记录。如果是小端的一千二百三十四:就是"4321"了。 通常应用一般而言,平台使用的大......
  • C++_函数模板
    函数模板》是不进行编译的,因为类型还不知道模板的实例化》函数调用点进行实例化:在函数调用点,编译器用用户指定的类型,从原模板实例化一份函数代码出来模板函数》才是要被编译器所编译的模板类型参数typename/class模板非类型参数模板的实参推演》可以根据用户传......
  • stm32用keil5新建C/C++写硬件串口模块的套路
    新建文件:写代码:就在这里开始写initSerial了..........