C++ 模板类与友元

模板类的友元函数有三类:
1)非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数。
2)约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
3)非约束模板友元:模板类实例化时,如果实例化了n个类,也会实例化n个友元函数,每个实例化的类都拥有n个友元函数。

1)非模板友元示例:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

template<class T1, class T2>
class AA    
{
    T1 m_x;
    T2 m_y;
public:
    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
    // 非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数,只能在类内实现。
    friend void show(const AA<T1, T2>& a)
    {
        cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
    }
   /* friend void show(const AA<int, string>& a);
    friend void show(const AA<char, string>& a);*/
};

//void show(const AA<int, string>& a)
//{
//    cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
//
//void show(const AA<char, string>& a)
//{
//    cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}

int main()
{
    AA<int, string> a(88, "我是一只傻傻鸟。");
    show(a);

    AA<char, string> b(88, "我是一只傻傻鸟。");
    show(b);
}

2)约束模板友元示例:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

// 约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
template <typename T>
void show(T& a);                                                 // 第一步:在模板类的定义前面,声明友元函数模板。

template<class T1, class T2>
class AA    // 模板类AA。
{
    friend void show<>(AA<T1, T2>& a);          // 第二步:在模板类中,再次声明友元函数模板。
    T1 m_x;
    T2 m_y;

public:

    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template<class T1, class T2>
class BB    // 模板类BB。
{
    friend void show<>(BB<T1, T2>& a);          // 第二步:在模板类中,再次声明友元函数模板。
    T1 m_x;
    T2 m_y;

public:

    BB(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template <typename T>                                 // 第三步:友元函数模板的定义。
void show(T& a)
{
    cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>                                                    // 第三步:具体化版本。
void show(AA<int, string>& a)
{
    cout << "具体AA<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>                                                    // 第三步:具体化版本。
void show(BB<int, string>& a)
{
    cout << "具体BB<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

int main()
{
    AA<int, string> a1(88, "我是一只傻傻鸟。");
    show(a1);         // 将使用具体化的版本。

    AA<char, string> a2(88, "我是一只傻傻鸟。");
    show(a2);        // 将使用通用的版本。

    BB<int, string> b1(88, "我是一只傻傻鸟。");
    show(b1);         // 将使用具体化的版本。

    BB<char, string> b2(88, "我是一只傻傻鸟。");
    show(b2);        // 将使用通用的版本。
}

3)非约束模板友元

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

// 非类模板约束的友元函数,实例化后,每个函数都是每个每个类的友元。
template<class T1, class T2>
class AA    
{
    template <typename T> friend void show(T& a);     // 把函数模板设置为友元。
    T1 m_x;
    T2 m_y;
public:
    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template <typename T> void show(T& a)                     // 通用的函数模板。
{
    cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>void show(AA<int, string>& a)                 // 函数模板的具体版本。
{
    cout << "具体<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

int main()
{
    AA<int, string> a(88, "我是一只傻傻鸟。");
    show(a);         // 将使用具体化的版本。

    AA<char, string> b(88, "我是一只傻傻鸟。");
    show(b);        // 将使用通用的版本。
}


推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家:
零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核)
https://xxetb.xet.tech/s/3Zqhgt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/760347.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

指针类型及数据读取和解释

指针类型的作用和解引用的过程 指针类型的作用&#xff1a; 根据指针类型确定读取数据位数&#xff08;float类型指针&#xff0c;读取32位&#xff09;&#xff1b;根据指针类型解释读取的数据&#xff08;float类型指针&#xff0c;按照1位符号位&#xff0c;8位指数位&…

(单机架设教程)3D剑踪

前言 今天给大家带来一款单机游戏的架设&#xff1a;3D剑踪 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; 3D剑踪 搭建教程 此游戏架设不需要虚拟机&#xff0c; 我们先解压 “3D剑踪.zip” &…

【计算机图形学 | 基于MFC三维图形开发】期末考试知识点汇总(上)

文章目录 视频教程第一章 计算机图形学概述计算机图形学的定义计算机图形学的应用计算机图形学 vs 图像处理 vs模式识别图形显示器的发展及工作原理理解三维渲染管线 第二章 基本图元的扫描转换扫描转换直线的扫描转换DDA算法Bresenham算法中点画线算法圆的扫描转换中点画圆算法…

老师如何发布期末成绩查询

期末成绩的发布总是让人既期待又紧张。但别担心&#xff0c;今天我就来和大家分享一下如何高效、准确地发布期末成绩查询&#xff0c;让家长和学生都能轻松查到成绩&#xff0c;同时也减轻你的工作负担。 整理成绩数据是关键。确保你的成绩单是最新的&#xff0c;并且已经经过仔…

架构师篇-10、DDD实战篇:通过领域模型落地系统

基于领域模型的设计与开发 数据库设计程序设计微服务设计 在线订餐系统的领域事件通知 微服务拆分 事件风暴会议 梳理领域事件进行领域建模识别聚合关系划分限界上下文 用户下单领域模型 更新后的模型 领域模型的设计实现过程 数据库设计 数据库映射&#xff1a;一对一关系…

【Mac】Auto Mouse Click for Mac(高效、稳定的鼠标连点器软件)软件介绍

软件介绍 Auto Mouse Click for Mac 是一款专为 macOS 平台设计的自动鼠标点击软件&#xff0c;它可以帮助用户自动化重复的鼠标点击操作&#xff0c;从而提高工作效率。以下是这款软件的主要特点和功能&#xff1a; 1.自动化点击操作&#xff1a;Auto Mouse Click 允许用户录…

【硬件视界2】CPU和GPU:计算机架构的双子星

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 本篇笔记整理&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、CPU (中央处理器)①主要作用②特点 2、 GPU (图形处理…

Workerman在线客服系统源码,附搭建教程

源码介绍&#xff1a; Workerman在线客服系统源码。 workerman是一个高性能的PHP socket 服务器框架&#xff0c;workerman基于PHP多进程以及libevent事件轮询库&#xff0c;PHP开发者只要实现一两个接口&#xff0c;便可以开发出自己的网络应用&#xff0c;例如Rpc服务、聊天…

气膜仓库的优势与应用—轻空间

随着现代物流和存储需求的不断增长&#xff0c;传统仓库的建设和运营成本日益增加&#xff0c;企业需要寻找更加灵活、高效和经济的解决方案。在这种背景下&#xff0c;气膜仓库作为一种新型仓储形式&#xff0c;以其独特的优势和广泛的应用前景&#xff0c;逐渐受到市场的青睐…

Hadoop3:Yarn配置任务的优先级

一、需求说明 配置队列优先级 容量调度器&#xff0c;支持任务优先级的配置&#xff0c;在资源紧张时&#xff0c;优先级高的任务将优先获取资源。默认情况&#xff0c;Yarn将所有任务的优先级限制为0&#xff0c;若想使用任务的优先级功能&#xff0c;须开放该限制。 二、修…

【STM32嵌入式系统设计与开发---传感器拓展】——1_4_标准库FreeRTOS移植实验

目录 雅俗理解源码下载链接知识拓展步骤1&#xff1a;stm32f103vet6移植freeRTOS步骤:&#xff08;1&#xff09;准备开发环境&#xff08;2&#xff09;添加FreeRTOS移植 致谢 雅俗理解 雅&#xff1a;FreeRTOS是一个开源的实时操作系统&#xff08;RTOS&#xff09;&#xf…

index()方法——字符串首次出现的索引位置

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 index()方法用于查询一个字符串在其本身字符串对象中首次出现的索引位置。它与find()方法功能相同&#xff0c;区别在于当find()方法没有检…

数据产品经理知识库构建

概述 数据产品经理是企业中负责管理和推动数据产品的专业人员。他们利用数据来辅助决策&#xff0c;优化产品&#xff0c;提升用户体验。用STAR法则&#xff08;Situation, Task, Action, Result&#xff09;来介绍数据产品经理的角色&#xff0c;应该学习的数据产品&#…

cookie 的获取过程

#第一次请求过程 浏览器第一次发送请求时,不会携带任何cookie信息 服务器接收到请求之后&#xff0c;发现请求中没有任何cookie信息 服务器生成和设置一个cookie.并将此cookie设置通过set_cookie的首部字段保存在响应报文中返回给浏 览器 浏览器接收到这个响应报文之后,发现里…

人工智能 (AI) 在能源系统中应用的机会和风险

现代文明极度依赖于电力的获取。电力系统支撑着我们视为理所当然的几乎所有基本生活功能。没有电力的获取&#xff0c;大多数经济活动将是不可能的。然而&#xff0c;现有的电网系统并未设计来应对当前——更不用说未来的——电力需求。与此同时&#xff0c;气候变化迫切要求我…

1.linux操作系统CPU负载

目录 概述CPU平均负载查看平均负载结束 概述 CPU 使用率 和CPU 平均使用率。 CPU平均负载 单位时间内系统处于 [可运行状态] 和 [不可中断状态] 的平均进程数&#xff0c;就是平均活跃进程数&#xff0c;和CPU使用率并没有直接关系 可运行状态 正在使用CPU或者正等待CPU的进…

vscode 开发qt6 开发环境搭建

vscode代码编辑器有自己一些优势&#xff0c;考虑用它开发qt6项目&#xff1a; 整个配置过程如下&#xff1a; 插件安装&#xff1a; .mingw&cmake安装配置: qt creator 创建一个测试工程&#xff0c;当然&#xff0c;工程是cmake类型 &#xff1a; vsocode 打开cmakeLis…

❤ Gitee平台的使用

Gitee平台的使用 文章目录 Gitee平台的使用一、Gitee的注册1、注册2、添加邮箱 二、仓库的创建 和 团队成员的添加1、单击右上角的 **&#xff0b;** 号 、创建仓库2、如下填写即可 三、仓库克隆到本地1、安装好git 和 小乌龟&#xff08;TortoiseGit&#xff09;2、打开仓库 复…

计算机Java项目|基于SpringBoot的作业管理系统设计与实现

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、Python项目、前端项目、人工智能与大数据、简…

ThreadPoolExecutor 线程回收时机详解

个人博客 ThreadPoolExecutor 线程回收时机详解 | iwts’s blog 总集 想要完整了解下ThreadPoolExecutor&#xff1f;可以参考&#xff1a; 基于源码详解ThreadPoolExecutor实现原理 | iwts’s blog Worker-工作线程管理 线程池设计了内部类Worker&#xff0c;主要是用来…