iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++超详细讲解友元的使用
  • 271
分享到

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

2024-04-02 19:04:59 271人浏览 安东尼
摘要

目录一、友元的概念二、友元的用法三、友元的语法四、友元的尴尬五、注意事项六、小结一、友元的概念 什么是友元?友元是 c++ 中的一种关系友元关系发生在函数与类之间或者类与类之间友元关

一、友元的概念

  • 什么是友元?
  • 友元是 c++ 中的一种关系
  • 友元关系发生在函数与类之间或者类与类之间
  • 友元关系是单项的,不能传递

二、友元的用法

  • 在类中以 friend 关键字声明友元
  • 类的友元可以是其它类或者具体函数
  • 友元不是类的一部分
  • 友元不受类中访问级别的限制
  • 友元可以直接访问具体类的所有成员

三、友元的语法

在类中用 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;
}

输出结果如下:

四、友元的尴尬

  • 友元是为了兼顾 C 语言的高效而诞生的
  • 友元直接破坏了面向对象的封装性
  • 友元在实际产品中的高效是得不偿失的
  • 友元在现代软件工程中已经逐渐被遗弃

五、注意事项

  • 友元关系不具备传递性
  • 类的友元可以是其它类的成员函数
  • 类的友元可以是某个完整的类
  • 所有的成员函数都是友元

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

#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);
    }
    
};
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++超详细讲解友元的使用的文章就介绍到这了,更多相关C++友元内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++超详细讲解友元的使用

本文链接: https://www.lsjlt.com/news/147003.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++超详细讲解友元的使用
    目录一、友元的概念二、友元的用法三、友元的语法四、友元的尴尬五、注意事项六、小结一、友元的概念 什么是友元友元是 C++ 中的一种关系友元关系发生在函数与类之间或者类与类之间友元关系...
    99+
    2022-11-13
  • C++超详细讲解友元与内部类
    目录一.友元1.友元函数(1)引入原因(2)友元函数作用(3)友元函数特征2.友元类(1)解释(2)友元类特征二.内部类(不常用)1.概念2.特性 一.友元 友元分为: 友...
    99+
    2022-11-13
  • Python超详细讲解元类的使用
    目录类的定义一、什么是元类二、注意区分元类和继承的基类三、type 元类的使用四、自定义元类的使用类的定义 对象是通过类创建的,如下面的代码: # object 为顶层基类 clas...
    99+
    2022-11-11
  • C++BoostUtility超详细讲解
    目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速...
    99+
    2022-12-08
    C++ Boost Utility C++ Utility库
  • C++BoostUuid超详细讲解
    目录一、说明二、Boost.Uuid库示例和代码一、说明 Boost.Uuid 为 UUID 提供生成器。 UUID 是不依赖于中央协调实例的通用唯一标识符。例如,没有数据库存储所有...
    99+
    2022-12-08
    C++ Boost Uuid C++ Uuid标识符
  • C++超详细讲解模板的使用
    目录一、函数模板1.1函数模板概念1.2 函数模板格式1.3 函数模板的原理1.4 函数模板的实例化二、类模板2.1 类模板的定义格式2.2类模板的实例化总结一、函数模板 1.1函数...
    99+
    2022-11-13
  • C++BoostLockfree超详细讲解使用方法
    目录一、说明二、示例和代码Boost.Lockfree 一、说明 Boost.Lockfree 提供线程安全和无锁容器。可以从多个线程访问此库中的容器,而无需同步访问。 在 1.56...
    99+
    2022-11-21
    C++ Boost Lockfree C++ Lockfree方案
  • C++超详细讲解auto与nullptr的使用
    目录一. auto关键字1. auto介绍2. 使用规则3. auto不能推导的场景二. 基于范围的for循环(C++11)1. 范围for的语法2. 范围for的使用条件三. 指针...
    99+
    2022-11-13
  • C++ 超详细示例讲解list的使用
    目录一、list的介绍list的介绍二、list的使用2.1 list的构造函数2.2 list迭代器的使用2.3 list相关的容量大小相关的函数2.4 list数据的访问相关的函...
    99+
    2022-11-13
  • C++ 超详细讲解stack与queue的使用
    目录stack介绍和使用模拟实现stack的使用例题最小栈栈的弹出压入序列逆波兰表达式求值queue模拟实现容器适配器deque简介priority_queue优先级队列priori...
    99+
    2022-11-13
  • C++超详细讲解泛型
    目录1.了解泛型编程2.函数模板2.1简单示例2.2多个模板参数2.3模板实例化2.4模板和普通函数同时存在2.5函数模板不支持定义和声明分离3.类模板3.1简单示例3.2成员函数声...
    99+
    2022-11-13
  • C++ Boost Assign超详细讲解
    目录说明Exercise说明 Boost.Assign Boost.Assign 库提供了帮助函数来初始化容器或向容器添加元素。如果需要将许多元素存储在一个容器中,这些函数尤其有用。...
    99+
    2022-12-09
    C++ Boost Assign C++ Assign库
  • C语言超详细讲解指针的使用
    目录指针概述自身类型指向类型代码例子数值型指针字符型指针单字符字符数组字符串型指针字符数组总结指针概述 C语言中指针也可以认为是一种类型,不同于数值型和字符型的类型。推演过去指针变量...
    99+
    2022-11-13
  • C++ Boost Lockfree超详细讲解使用方法
    Boost Lockfree 是一个基于 C++ 的库,用于实现无锁的数据结构和算法。无锁的数据结构和算法是为了解决并发编程中的竞争...
    99+
    2023-08-16
    C++
  • C++超详细讲解标准库
    目录一、有趣的重载二、C++ 标准库三、小结一、有趣的重载 操作符 << 的原生意义是按位左移,例:1 <<2; 其意义是将整数 1 按位左移2位,即:000...
    99+
    2022-11-13
  • C++BoostPropertyTree示例超详细讲解
    目录一、提要二、应用示例练习一、提要 借助类 boost::property_tree::ptree,Boost.PropertyTree 提供了一个树结构来存储键/值对。树形结构意...
    99+
    2022-11-13
    C++ Boost PropertyTree C++ Boost PropertyTree示例
  • C++BoostVariant示例超详细讲解
    目录一、提要二、示例一、提要         Boost.Variant 提供了一个类似于 unio&...
    99+
    2022-11-13
    C++ Boost Variant C++ Boost Variant示例
  • C++BoostOptional示例超详细讲解
    目录一、概述二、Boost.Optional一、概述 数据结构类似于容器,因为它们可以存储一个或多个元素。但是,它们与容器不同,因为它们不支持容器通常支持的操作。例如,使用本部分介绍...
    99+
    2022-11-13
    C++ Boost Optional C++ Boost Optional示例
  • C语言超详细讲解getchar函数的使用
    目录一、getchar 函数二、缓冲区1、什么是缓冲区2、为什么要存在缓冲区3、缓冲区的类型4、缓冲区的刷新三、getchar 函数的正确使用1、getchar 的换行问题2、get...
    99+
    2022-11-13
  • C++超详细讲解引用和指针
    目录引用概念定义步骤引用必须初始化引用初始化后不能更改引用作为函数的参数可以替代指针变量常引用引用作为函数的返回值类型引用的本质指针的引用(了解)指针和引用的区别引用概念 引用的本质...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作