C++ 类模板之类外实现重载运算符和友元函数

2023-11-15

在同一个CPP中,使用友元函数,同时在类外实现,这里.h .cpp未分离,如果分离写法不一样。
一般在使用类模板时,将声明和实现放在同一文件中,可命名为.hpp后缀,即.h .cpp在同一文件中

1.重载操作符

定义一个类,通过重载<< 打印输出该类的成员;

方法1,、
在类中声明该函数,同时前面加上 template <class T1, class T2>

  template <class T1, class T2>
  friend std::ostream&  operator<<(std::ostream& os, Person<T1, T2>& p);

方法2:
1)类内写完frien语句后,需要在类外声明本类并且声明友元函数。
2)在friend的语句中加上<>。

//在类外进行前置声明
template <class T1, class T2> std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p);friend的语句中 << 后 加上<T1,T2>
 friend std::ostream& operator<<<T1,T2>(std::ostream& os, Person<T1, T2>& p);

完整程序如下:

#include <iostream>
using namespace std;

//在类外进行前置声明

// 友元函数在类外面实现,并且都在同一个CPP文件中,
//需要在前面对类和对应操作符重载函数进行前置声明。
// 同时在类内部声明的对应函数需要在参数链表前加入 "<T>"。
template <class T1, class T2> class Person;
template <class T1, class T2> std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p);

//类模板 类外实现
//类模板
template <class T1, class T2> 
class Person {
public:
  //模板类中使用友元
  //重载左移操作符,用于直接打印输出
  //方法1
  //template <class T1, class T2>  //定要加 这句,不过这样的写法在linux不能通过
  //friend std::ostream&  operator<<(std::ostream& os, Person<T1, T2>& p);
  
  //方法2在操作符后加 <T1,T2>,同时进行类前置声明
  //方法1 在VS中可以便宜,但 要在Linux下会出错
  friend std::ostream& operator<<<T1,T2>(std::ostream& os, Person<T1, T2>& p);
  Person(T1 id, T2 age);
  void showPerson();

private:
  T1 mId_;
  T2 mAge_;
};

//声明和实现分开时,我们需要对函数的声明做特殊处理,
//注意,这里类名应是Person<T1,T2>
template <class T1, class T2> 
Person<T1, T2>::Person(T1 id, T2 age) {
  this->mAge_ = age;
  this->mId_ = id;
}

template <class T1, class T2> void Person<T1, T2>::showPerson() {
  std::cout << "id.....:" << mId_ << ",age:" << mAge_ << std::endl;
}


//通过重载左移操作符,用于直接打印输出
template <class T1, class T2>
std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p) {
  std::cout << "operator---  id: " << p.mId_ << ",age:" << p.mAge_ << std::endl;
  return os;
}


//类模板在类外实现时,不要滥用友元
void testShow() {
  //函数模板在调用时,可以自动进行类型推导
  //类模板必须显式声明
  Person<int, int> person(12, 11111);
  //person.showPerson();
  std::cout << "ddd: " << person << std::endl;
}

int main() {
  testShow();
  return 0;
}

2.使用普通友元函数

使用普通友元函数与上面的操作符重载,是同样的操作方法,
完成程序如下:

#include <iostream>
using namespace std;

//方法2  在类外进行前置声明
template <class T1, class T2> class Person;
template <class T1, class T2> std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p);


//类模板 类外实现
//类模板
template <class T1, class T2> 
class Person {
public:
  //使用普通友元函数进行类外输出
  
  //方法1
  //template <class T1, class T2>
  //friend void printPerson(Person<T1, T2>& p);
  
  //方法2
  //应推荐的写法,把类进行前置声明
  friend void printPerson<T1,T2>(Person<T1, T2>& p);

  Person(T1 id, T2 age);
  void showPerson();

private:
  T1 mId_;
  T2 mAge_;
};

//声明和实现分开时,我们需要对函数的声明做特殊处理,
//注意,这里类名应是Person<T1,T2>
template <class T1, class T2> 
Person<T1, T2>::Person(T1 id, T2 age) {
  this->mAge_ = age;
  this->mId_ = id;
}

template <class T1, class T2> void
 Person<T1, T2>::showPerson() {
  std::cout << "id.....:" << mId_ << ",age:" << mAge_ << std::endl;
}


template <class T1, class T2>
void printPerson(Person<T1, T2>& p) {
	std::cout << "printPerson, id: " << p.mId_ << ",age:" << p.mAge_ << std::endl;

}
//类模板在类外实现时,不要滥用友元
void testShow() {
  //函数模板在调用时,可以自动进行类型推导
  //类模板必须显式声明
  Person<int, int> person(12, 11111);
  printPerson(person);
}

int main() {
  testShow();
  return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 类模板之类外实现重载运算符和友元函数 的相关文章

随机推荐

  • 浅谈测试开发岗位

    一 测试开发的概念与需求 测试开发 通常也被称为自动化测试 是一个涵盖了从测试设计 开发 执行和结果分析等一系列活动的职位 在软件开发的生命周期中 测试开发起着至关重要的作用 其主要目标是确保软件的质量和性能达到预期的标准 测试开发工程师通
  • MySQL查看当前数据库视图-SQL语句

    引言 查询语句为 show full tables where table type 可查询当前数据库表 一 创建一个视图 创建视图 create view v stu as 视图内容 连接的一个表 select name from t s
  • Stm32待机模式的进入与唤醒

    1 基础介绍 1 1 单片机的 低功耗模式 像是手机的待机模式 不同于正常运行模式 处于一种省电省资源的状态 1 2 在运行情况下 HCLK为cpu提供时钟 cortex m3内核执行程序的代码 如果处于中断事件的等待时 可以进入低功耗模式
  • 基于R语言分析身高与体重的相关性分析

    本博文源于暨南大学的 多元数据统计分析及R语言建模 旨在讲述身高与体重相关性分析 在概率论与数理统计课程中 两个变量之间协方差的标准化 因此先要熟悉并回忆公式 套用在R语言即可 例子 分析身高 kg 与体重 cm 的相关性 gt x1 c
  • 小心情

    好久没写博客了 总结下现在的自己 还是依旧那么的 情绪控 变化那么快 有时 都受不了自己的 坏脾气 学习再也没像原来的那么卖力 有那么点的小颓废 实验室布置的任务有那么点的小懈怠 一切都没有进展 生活依旧那么平淡 却也没有自己想要的那种安逸
  • linux内核对于指令异常的处理

    1 处理流程 以arm64来介绍一下流程 如果在用户层发生指令异常时 首先进入入口el0 undef arch arm64 kernel entry s el0 undef Undefined instruction enable inte
  • Jina 3.14 版本发布!支持独立部署Executor

    Jina 是一个 MLOps 框架 赋能开发者在云上构建多模态 跨模态的应用程序 Jina 能够将 PoC 提升为生产就绪服务 基础设施的复杂性交给 Jina 开发者能够直接轻松使用高级解决方案和云原生技术 GitHub https git
  • mysql免安装版的下载与安装

    下载 打开 https www mysql com downloads 1 点击该项 2 进去后点击 3 到了真正的下载页面 选择平台 选择版本 安装版和免安装版 下载 4 我现在下载免安装版的 Windows x86 64 bit ZIP
  • Python基础-将变量的值作为变量名

    使用场景 linux unix磁盘文件系统实时使用情况动态收集 每一台机器挂载的文件系统名字有可能都不相同 就算同一台机器不同时间段挂载的文件系统也会不同 我们需要动态收集文件系统名 将变量的值作为变量 定义为文件系统的名 语法基础 gt
  • java如何将字符串存入到数组中

    方法一 public static void main String args 定义一个字符串 String str browser 定义一个字符数组 char array new char 100 for int i 0 i lt str
  • liberity 添加信赖的https证书到key.jks

    业务场景 定时任务批量推送数据到第三方接口 请求地址为https 域名 测试环境测试之后 出现证书认证问题 不能正常推送数据 定时任务部署在 websphere liberty中 出现问题之后在java的Java jdk 1 8 jre l
  • webpack 压缩图片

    问题描述 vue正常打包之后一些图片文件很大 使打包体积很大 通过image webpack loader插件可将大的图片进行压缩从而缩小打包体积 参考 点这里 解决方法 一定要用cnpm安装 cnpm i image webpack lo
  • 数据结构Java实现05----栈:顺序栈和链式堆栈

    本文转载至 http www cnblogs com smyhvae p 4789699 html 一 堆栈的基本概念 堆栈 也简称作栈 是一种特殊的线性表 堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同 其差别是线性表允许在任意位
  • 数据库的优化方案

    1 优化索引 SQL语句 分析慢查询 2 设计表的时候严格根据数据库的设计凡事来设计数据库 3 使用缓存 把经常访问到的数据且不经常变化的数据放在缓存中 节约磁盘IO 4 优化硬盘 采用SSD 使用磁盘队列技术 5 采用MySQL内部自带的
  • 软件体系结构-KWIC索引系统

    引言 KWIC作为一个早年间在ACM的Paper提出的一个问题 被全世界各个大学的软件设计课程奉为课堂讲义或者作业的经典 From Wiki FYI D L Parnas uses a KWIC Index as an example on
  • Scala递归删除某个文件夹

    check the result is already exists or not val outFilePath D doc spark out t2 val outFile new File outFilePath recursion
  • arm 使用wpa_cli连接wifi

    公司使用的是IMX6的ARM板 板子已经带了8192cu的驱动 使用 lsmod 命令可以查看已经安装的mod 使用的USB为 树莓派 Raspberry Pi 无线USB网卡 EDUP EP N8508GS 黄金版 免驱 lsmod 结果
  • Lorenz系统、简单的Rossler系统和Chua电路系统的混沌吸引子——MATLAB实现

    1 Lorenz系统 美国著名气象学家E N Lorenz在1963年提出来的用来刻画热对流不稳定性的模型 即Lorenz混沌模型 可以简单描述如下 x
  • OpenFire源码学习之十六:wildfire

    Wildfire Wildfire是一个基于xmpp的IM即时通讯和群组聊天工具 安装 Windows Windows的默认安装目录 c ProgramFiles Wildfire Linux Unix 有两种选择方法 1 选择RPM 它将
  • C++ 类模板之类外实现重载运算符和友元函数

    在同一个CPP中 使用友元函数 同时在类外实现 这里 h cpp未分离 如果分离写法不一样 一般在使用类模板时 将声明和实现放在同一文件中 可命名为 hpp后缀 即 h cpp在同一文件中 1 重载操作符 定义一个类 通过重载 lt lt