全局函数类内实现-直接在类内声明友元即可

全局函数类外实现-需要提前让编译器知道全局函数的存在

#include <iostream>
using namespace std;//通过全局函数来打印Person的信息template<class T1,class T2>
class Person{//全局函数,类内实现friend void printPerson(Person<T1,T2> p){cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;}public:Person(T1 name,T2 age){this->m_Name=name;this->m_Age=age;}private:T1 m_Name;T2 m_Age;};
//1.全局函数在类内实现
void test01()
{Person<string,int> p("Tom",20);printPerson(p);
}
int main()
{test01();return 0;
}

你看,其实一开始m_Name和m_Age是一个私有的属性,因为其前面有private关键字,因此前面加上friend,也就是友元的全局函数才能访问这个私有属性。

全局函数在类外实现的时候

#include <iostream>
using namespace std;//通过全局函数来打印Person的信息
template<class T1,class T2>
class Person{//全局函数,类内实现friend void printPerson2(Person<T1,T2> p);// {//     cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;// }public:Person(T1 name,T2 age){this->m_Name=name;this->m_Age=age;}private:T1 m_Name;T2 m_Age;};
//1.全局函数在类内实现
// void test01()
// {
//     Person<string,int> p("Tom",20);
//     printPerson(p);
// }
//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
//全局函数在类外实现的测试
void test02()
{Person<string,int> p("Jerry",28);printPerson2(p);
}
int main()
{test02();return 0;
}

其会出现一个无法解析的错误。

    friend void printPerson2(Person<T1,T2> p);

这是一个普通函数的函数声明。

但是下面这是一个函数模版的实现,因此就导致了这两个不是一个东西。因此我们需要告诉编译器这是一个函数模版的声明。

//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
#include <iostream>
using namespace std;template<class T1,class T2>
class Person;template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}//通过全局函数来打印Person的信息
template<class T1,class T2>
class Person{//全局函数,类内实现//加空模版的参数列表friend void printPerson2(Person<T1,T2>p){cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;}friend void printPerson2<>(Person<T1,T2> p);public:Person(T1 name,T2 age){this->m_Name=name;this->m_Age=age;}private:T1 m_Name;T2 m_Age;};
//1.全局函数在类内实现
// void test01()
// {
//     Person<string,int> p("Tom",20);
//     printPerson(p);
// }
//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2>& p)
{cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
//全局函数在类外实现的测试
void test02()
{Person<string,int> p("Jerry",28);printPerson2(p);
}
int main()
{test02();return 0;
}

一般没有特殊需求的话,直接就写全局函数配合类内实现就完事儿了,用法非常简单,而且编译器可以直接识别。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux Java环境配置

1.进入java官网&#xff0c;点击Java archive Java Downloads | Oracle 中国https://www.oracle.com/cn/java/technologies/downloads/ 2.然后下滑选择你要安装的java版本&#xff0c;这里我选择的是java8 3.依据系统架构选择版本安装&#xff0c;x86&#xff0c;x64&#xf…

flutter app内跳转到其他安卓 app的方法

flutter 内的关键代码导包&#xff1a;url_launcher: ^6.3.1跳转逻辑&#xff1a;onPressed: () async {await launchUrl(Uri.parse(demoname://));},安卓内的关键代码<intent-filter><action android:name"android.intent.action.VIEW" /><category …

医疗资质OCR智能审核:让合规管理更高效、更精准

在医疗行业&#xff0c;资质证件的审核是确保机构合规运营的关键环节。从医疗机构执业许可证到医师资格证&#xff0c;从药品经营许可证到医疗器械注册证&#xff0c;传统人工审核方式效率低下且容易出错。现在&#xff0c;医疗资质OCR智能审核解决方案正在重塑行业标准&#x…

利用 Spring 的 `@Scheduled` 注解结合简单的状态跟踪实现空闲检测方案

一种基于定时任务和简单状态跟踪的方法: 实现思路 记录用户的最后活动时间:每当用户进行某些操作(如点击、请求等),更新其最后活动的时间戳。 使用定时任务检查用户是否空闲:设置一个后台任务,定期检查每个用户的最后活动时间,判断是否超过了设定的空闲时间阈值。 执行…

如何在 Ubuntu 上安装 Microsoft Edge 浏览器?

Microsoft Edge 是 Microsoft 在2015年开发的跨平台浏览器&#xff0c;最初是建立在他们自己的浏览器引擎和 Chakra JavaScript 引擎之上的&#xff0c;此浏览器可防止恶意网站和下载文件。 本文将帮助您在 Ubuntu 系统上安装 Microsoft Edge 浏览器。 1: 下载 Edge Browser …

16路串口光纤通信FPGA项目实现指南 - 第二部分(下)

16路串口光纤通信FPGA项目实现指南 - 第二部分&#xff08;下&#xff09; 五、核心控制逻辑实现&#xff08;接收部分&#xff09; 5.4 数据接收控制逻辑 // 接收数据寄存逻辑 reg rs422_rx_valid; // 接收数据有效信号 reg [15:0] rs422_rx_data; // 接收数据寄存器…

前后端分离项目的完整部署(Jenkins自动化部署)

人工部署方式&#xff0c;参考文章&#xff1a; 前后端分离项目的完整部署&#xff08;人工部署&#xff09;-CSDN博客 目标 在Windows操作系统上&#xff0c;使用Jenkins完成源代码的自动拉取、编译、打包、发布工作。 项目背景 前端使用vue&#xff0c;程序打包后为dist目…

Python设计模式深度解析:装饰器模式(Decorator Pattern)完全指南

Python设计模式深度解析&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09;完全指南前言什么是装饰器模式&#xff1f;装饰器模式的核心思想Python函数装饰器&#xff1a;从基础到高级基础函数装饰器高级函数装饰器实现GUI装饰器模式&#xff1a;动态界面增强Tk…

JVM--虚拟线程

首先了解一个理念&#xff1a;线程与 OS 线程 1:1 绑定在传统 Java 线程&#xff08;平台线程&#xff09;模型中&#xff1a;每个 Java 线程直接对应一个操作系统级别的线程操作系统负责调度这些线程线程的创建、管理和调度都由操作系统内核处理这种模型称为 1:1 线程模型&…

掌握系统设计的精髓:12个核心设计模式的通俗解读

在构建复杂且高可用的软件系统时&#xff0c;仅仅了解编程语言和算法是不够的。真正的挑战在于如何设计出能够应对并发、故障、扩展等各种问题的健壮架构。系统设计模式正是前辈们在无数实践中提炼出的智慧结晶&#xff0c;它们是解决常见系统问题的“最佳实践”。 本文将深入浅…

概率论与数理统计(二)

事件的概率 概率&#xff1a;可能性的大小 古典概率模型&#xff1a; 1&#xff09;有限个样本点 2&#xff09;等可能性 P(A)A中包含的基本事件数基本事件总和 P(A) \frac{A中包含的基本事件数}{基本事件总和} P(A)基本事件总和A中包含的基本事件数​ 频率与概率 nnn 次实验…

新型eSIM攻击技术可克隆用户资料并劫持手机身份

eSIM技术存在重大安全漏洞研究人员发现eSIM技术中存在一个关键漏洞&#xff0c;攻击者可利用该漏洞克隆移动用户资料并劫持手机身份。AG安全研究团队宣布&#xff0c;他们成功攻破了采用GSMA消费者证书的Kigen eUICC&#xff08;嵌入式通用集成电路卡&#xff09;安全防护&…

langchain教程2:更加高级和灵活的Prompt模板

文章目录 prompt模板 对话Prompt模板 函数大师 使用jinja2与f-string实现提示词模板格式化 组合式提示词模板 prompt模板 from langchain.prompts import PromptTemplateprompt = PromptTemplate.from_template("你是一个{name},帮我起一个具有{country}特色的{gender}名…

UE5使用Motion Warping有什么用?

在 UE5 中&#xff0c;Motion Warping 是一套用于「动态调整根运动动画」的系统插件&#xff0c;它能让带有根运动&#xff08;Root Motion&#xff09;的动画根据游戏运行时的环境自动变形&#xff08;Warp&#xff09;&#xff0c;以更精准地贴合目标位置或目标方向&#xff…

类模版的相关案例

案例实现&#xff1a;实现一个通用的数组类&#xff0c;要求如下&#xff1a;可以对内置数据类型以及自定义数据类型的数据进行存储将数组中的数据存储到堆区构造函数中可以传入数组的容量提供对应的拷贝构造函数以及operator防止浅拷贝问题提供尾插法和尾删法对数组中的数据进…

服务器端安全检测与防御技术概述

一、服务器安全风险1.不必要的访问&#xff08;如只提供HTTP服务&#xff09;--应用识别控制2.公网发起IP或端口扫描、DDOS攻击等--防火墙3.漏洞攻击&#xff08;针对服务器操作系统等&#xff09;--IPS4.根据软件版本的已知漏洞进行攻击&#xff0c;口令暴力破解、获取用户权限…

前端性能与可靠性工程系列: 渲染、缓存与关键路径优化

前端性能与可靠性工程系列: 渲染、缓存与关键路径优化 第一部分:揭秘浏览器 - 关键渲染路径 (CRP) 关键渲染路径 (Critical Rendering Path - CRP) 是指浏览器从接收到最初的 HTML、CSS 和 JavaScript 字节,到最终将它们渲染成可见像素所必须经过的一系列步骤。我们的目标,…

基于CentOS的分布式GitLab+Jenkins+Docker架构:企业级CI/CD流水线实战全记录

引言&#xff1a;从单机到分布式容器架构的演进在传统Web应用部署中&#xff0c;我们常常面临环境不一致、部署效率低下等问题。我曾经维护过一个需要手动在5台服务器上重复部署的游戏项目&#xff0c;每次发布都如同走钢丝。本文将详细分享如何基于CentOS系统&#xff0c;构建…

JVM——为什么Java8移除了永久代(PermGen)并引入了元空间(Metaspace)?

Java8移除永久代并引入元空间&#xff0c;主要是为了解决 PermGen 固定大小、容易导致内存溢出、GC 效率低的问题。元空间使用本地内存&#xff0c;具备更灵活的内存分配能力&#xff0c;提升了垃圾收集和内存管理的效率。 PermGen 的局限性 ①固定大小:永久代的内存空间大小在…

3.正则化——新闻分类

影响结果出了最终的目标&#xff0c;还会有许多细节因素 在机器学习中&#xff0c;往往会面临很多过拟合和欠拟合的问题。 欠拟合是训练不到位&#xff0c;过拟合是训练过头&#xff0c;会导致泛化性差正则化是在损失函数中添加一个惩罚项&#xff0c;以简化模型对于惩罚项Pena…