类模板里面的函数写在类模板里面和写在类模板的外面,且在1个.cpp文件中
和类一样,类模板里面声明的函数,其函数体写在类里面和外面都行,但是有一点需要注意:1.用友元函数重载<< 或 >>运算符,函数声明写在类模板里面,函数实现写在类模板外面,要在函数名和函数输入参数之间写上Typename定义的那个类型,如template <typename T>,则应写上<T>。举个例子,如果重载运算符<<,且重载函数的函数体写在类模板的外面,则在类模板里面声明重载函数时,函数声明应该写成ostream operator<< <T> (ostream&,类模板名<T>&)。
上面这个知识点是很多新手易犯的错误,很多人在网上跪求原因,一定要注意!
2.一般性的友元函数,函数声明写在类模板里面,函数实现写在类模板外面,需要在类的前面添加函数的前置声明,否则编译肯定通不过。因为这个方法比较复杂,所以碰到类模板的时候,能不用友元函数尽量不要用友元函数。
在类的前面添加前置函数声明的方法如下:
1)template <Typename T>
class Complex //这里假定类模板的名字就是Complex,这句话是类的前置声明
template <Typename T>
Complex<T> myfun(class<T>& ,class<T>&) //函数的前置声明
2)在类模板的内部声明应写成:friend Complex myfun<T>(Complex& ,Complex&) ,这里必须要加<T>
3)友元函数在类模板外面的实现写成:
Complex<T> myfun(class<T>& c1 ,class<T>& c2)
{...}
4)友元函数的调用写成:myfun<int>(c1,c2),这里<int>也是必须要加的
究其原因,与C++编译器对类模板的二次编译有关。当C++编译器遇到类模板里面的函数声明时,生成一个函数头;遇到类模板外面的函数体实现时,又生成了一个函数头。因为友元函数是全局函数,它不属于类模板,所以两次生成的函数头不一样,导致了C++编译器找不到由原函数的函数体实现了,所以编译就会报错。而且不同的编译器,可能有的支持这个语法,有的不支持这个语法,所以碰到函数模板时一定要谨慎使用友元函数,能不用就不要用。
下面是具体实例:
1 #include <iostream> 2 3 using namespace std; 4 5 /* 6 //1.类模板的函数都写在类的内部 7 template <typename T> 8 class Complex 9 { 10 friend ostream& operator<<(ostream& out,Complex& c) 11 { 12 out<<c.a<<"+"<<c.b<<"i"; 13 return out; 14 } 15 16 public: 17 Complex(T a,T b) 18 { 19 this->a=a; 20 this->b=b; 21 } 22 23 Complex operator+(Complex& c) 24 { 25 Complex temp(this->a+c.a,this->b+c.b); 26 return temp; 27 } 28 29 void printCom() 30 { 31 cout<<this->a<<"+"<<this->b<<"i"<<endl; 32 } 33 34 private: 35 T a; 36 T b; 37 }; 38 */ 39 40 //2.类模板的函数都写在类的外部 41 template <typename T> 42 class Complex 43 { 44 //注意,友元函数在类模板的类体里面声明的时候,在函数的名字和函数参数类型之间加了一个<T>,若不加这个<T>,则编译通不过! 45 friend ostream& operator<<<T>(ostream& out,Complex& c); 46 47 public: 48 Complex(T,T);//构造函数 49 Complex operator+(Complex& );//重载“+”操作符 50 void printCom();//普通函数 51 52 private: 53 T a; 54 T b; 55 }; 56 57 //注意友元函数在类体里面的声明的写法! 58 template <typename T> 59 ostream& operator<<(ostream& out,Complex<T>& c) 60 { 61 out<<c.a<<"+"<<c.b<<"i"; 62 return out; 63 } 64 65 template <typename T> 66 Complex<T>::Complex(T a,T b) 67 { 68 this->a=a; 69 this->b=b; 70 } 71 72 template <typename T> 73 Complex<T> Complex<T>::operator+(Complex<T>& c) 74 { 75 Complex<T> temp(this->a+c.a,this->b+c.b); 76 return temp; 77 } 78 79 template <typename T> 80 void Complex<T>::printCom() 81 { 82 cout<<this->a<<"+"<<this->b<<"i"<<endl; 83 } 84 85 int main() 86 { 87 Complex<float> c1(1.2,2.5),c2(3.2,5.3); 88 89 c1.printCom(); 90 c2.printCom(); 91 92 cout<<c1+c2<<endl; 93 94 return 0; 95 }
转载于:https://www.cnblogs.com/jswu-ustc/p/8514434.html
类模板里面的函数写在类模板里面和写在类模板的外面,且在1个.cpp文件中相关推荐
- 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中
将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...
- boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序
boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回 ...
- boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测试程序
boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测 ...
- boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序
boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序 ...
- boost::regex模块在 cpp 文件中搜索类定义,使用 C++ Builder 闭包作为回调的测试程序
boost::regex模块在 cpp 文件中搜索类定义,使用 C++ Builder 闭包作为回调的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类 ...
- boost::regex模块实现在 cpp 文件中搜索类定义的测试程序
boost::regex模块实现在 cpp 文件中搜索类定义的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块实现在 cpp 文件中搜索类定义的测试程序 C++实现代码 #i ...
- C++ 在一个cpp文件中使用另一个cpp文件中定义的函数
C++ 在一个cpp文件中 使用另一个cpp文件中定义的函数 建立一个console项目 头文件 cpp文件 main.cpp 建立一个console项目 以dev为例,在[文件][新建][项目],新 ...
- abstract类中不可以有private的成员_C++ 类:声明成员函数与实现
接上文... 16.3类的成员 2.成员函数 1.构造函数 ... 2.拷贝构造函数 有了类的构造函数我们就可以创建类的实例了,下图中分别使用不同的构造函数一共创建了4个动物的对象,现在程序中就有4个 ...
- C++:运算符重载与类的赋值运算符重载函数
目录 章节知识架构 一.运算符重载 1. 运算符重载的基本概念 代码段1 2.关于运算符重载的重要语法细则 二.运算符重载在类中的使用 三.类的默认成员函数:=重载函数(赋值运算符重载) 1.自定义= ...
最新文章
- Facebook 开源了一整套重要的 Linux 内核组件与工具!
- 表格单元格中的CSS文本溢出?
- linux pfn,ARM Linux下的page和pfn之间转换的宏。
- access开发精要(3)-子数据表
- uniapp 页面下次渲染完成后执行:this.$nextTick
- C/C++学习之路: 多态
- SQL Server 无法生成 FRunCM 线程。请查看 SQL Server 错误日志和 Windows 事件日志(转)...
- linux中安装jdk安装(rpm安装)
- fineuploader php服务端
- opencv4版本和3版本_Spring Boot 太狠了,一口气发布了 3 个版本!
- Oracle中表pagesize,Oracle使用pagesize命令
- 扁平化设计的流行配色方案
- m低信噪比下GPS信号的捕获算法研究,使用matlab算法进行仿真
- FANUC机器人示教时遇到奇异点的解决办法
- 计算机主板别称是什么城,武汉别名江城又称什么城 武汉被誉为什么城之称
- graylog+kafka+zookeeper(单机测试及源码),graylog测试用例及源码(三)
- 常用标点符号的英文名称
- Camera基本结构及原理
- 最长递增子序列的O(NlogN)算法
- 微信点开分享文章所带的关键字
热门文章
- SSH框架之Maven
- 中国信息化系统集成行业协会:计算机系统集成行业还有发展空间么?
- java oj题及答案_华为OJ答案(java版)题目2
- UE4学习笔记:学习UE4中的UMG(图形UI设计器)工具(四):UMG中的动画
- Euler-Maruyama 方法数值算例
- Windows安装DB2
- 使用 SAP WebIDE 开发 SAP Fiori Worklist 应用消费 OData 服务
- 大数据时代,人流量统计系统如何提高商业价值
- 数据结构背包问题c语言思路,C语言学习趣事_数据结构_经典命题_1_背包问题_分析_1...
- Mac下不用虚拟机一样可以使用PLSQL Developer