C++ 模板类友元之输出流操作符重载
几个关键点:
需要前置声明!--奇怪的是别人告诉我也可以不需要,但我这里不行!
友元函数的函数名后面的<>,必须要有。
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- //前置声明,你妹啊
- template<class T> class A;
- template<class T> ostream &operator<< (ostream &out, const A<T> &_a);
- template<class T1, class T2> class B;
- template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b);
- template<class T> class A
- {
- public:
- A(){}
- A(T _a, T _b):a(_a),b(_b){}
- ~A(){}
- private:
- T a;
- T b;
- friend ostream &operator<< <> (ostream &out, const A<T> &a);
- };
- template<class T> ostream &operator<< (ostream &out, const A<T> &_a){
- out<<_a.a<<"--"<<_a.b;
- return out;
- }
- template<class T1, class T2> class B: public A<T1>
- {
- public:
- B(){}
- B(T1 _a, T1 _b, T2 _c):A<T1>(_a,_b),c(_c){} //A<T1>
- ~B(){}
- private:
- T2 c;
- friend ostream &operator<< <>(ostream &out, const B<T1, T2> &_b);
- };
- template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b){
- // out<<(A<T1>)_b;
- // out<<"--"<<_b.c;
- out<<(A<T1>)_b<<"--"<<_b.c;
- return out;
- }
- int main(int argc, char const *argv[])
- {
- A<int> x(, );
- B<char, int> y('a', 'b', );
- cout<< x <<endl;
- cout<< y <<endl;
- return ;
- }
以上认识太片面,请忽略。
这里 有完美的解释!
大意如下:
模板类的友元其实有多个可能,关键在于这个友元是该模板类的一个/特定具现(实例)的友元,还是所有具现(实例)的友元。
注意1,这里不需要考虑与泛型无关的友元--例如输出一句话之类的,完全没有意义。
注意2,这里的多个可能是编译之前的可能,编译之后还是一个具现(实例)有一个友元(---猜测)。
总之,我认为,这两种仅仅是出发点不同,但最终目的地一致。
一、友元是模板类的一个/特定具现(实例)的友元,需要前置声明:
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- //前置声明,你妹啊
- template<class T> class A;
- template<class T> ostream &operator<< (ostream &out, const A<T> &_a);
- template<class T1, class T2> class B;
- template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b);
- template<class T> class A
- {
- public:
- A(){}
- A(T _a, T _b):a(_a),b(_b){}
- ~A(){}
- private:
- T a;
- T b;
- friend ostream &operator<< <> (ostream &out, const A<T> &a);
- };
- template<class T> ostream &operator<< (ostream &out, const A<T> &_a){
- out<<_a.a<<"--"<<_a.b;
- return out;
- }
- int main(int argc, char const *argv[])
- {
- A<int> x(, );
- cout<< x <<endl;
- return ;
- }
二、友元是所有具现(实例)的友元,不需要前置声明:
- #include <iostream>
- using namespace std;
- //友元operator<< 是模板类A的所有实例的友元(实际上还是多个operator<<)--不需要前置声明。
- template <typename T>
- struct A {
- T a;
- A(T _a) :a(_a) {}
- template <typename T1> friend ostream &operator<< (ostream &out, const A<T1> &_a);//这里的T1?? 由于<<输出的是A的实例的对象,所以实际上这里的T1编译之后还是T--因为编译器找不到其他可能。
- };
- template <typename T>
- ostream & operator<< (ostream & out, const A<T> &_a) {
- out << _a.a;
- return out;
- }
- int main() {
- A<int> x();
- cout << x << endl;
- return ;
- }
C++ 模板类友元之输出流操作符重载的更多相关文章
- 15.C++-操作符重载、并实现复数类
首先回忆下以前学的函数重载 函数重载 函数重载的本质为相互独立的不同函数 通过函数名和函数参数来确定函数调用 无法直接通过函数名得到重载函数的入口地址 函数重载必然发生在同一个作用域中 类中的函数重载 ...
- C++中的链表节点用模板类和用普通类来实现的区别
C++中的链表节点通常情况下类型都是一致的.因此我们可以用模板来实现. #include <iostream> using namespace std; template<typen ...
- C++中的操作符重载
一.什么是操作符重载 操作符重载可以分为两部分:“操作符”和“重载”.说到重载想必都不陌生了吧,这是一种编译时多态,重载实际上可以分为函数重载和操作符重载.运算符重载和函数重载的不同之处在于操作符重载 ...
- 15.C++-操作符重载
首先回忆下以前学的函数重载 函数重载 函数重载的本质为相互独立的不同函数 通过函数名和函数参数来确定函数调用 无法直接通过函数名得到重载函数的入口地址 函数重载必然发生在同一个作用域中 类中的函数重载 ...
- C++解析(17):操作符重载
0.目录 1.操作符重载 2.完善的复数类 3.小结 1.操作符重载 下面的复数解决方案是否可行? 示例1--原有的解决方案: #include <stdio.h> class Compl ...
- c++之旅:操作符重载
操作符重载 操作符重载可以为操作符添加更多的含义,操作符重载的作用的对象是类 那些操作符可以重载 除了下面几个操作符不能重载外,其它的操作符都能重载 . :: .* ?: sizeof 操作符重载的本 ...
- 操作符重载(day07)
二十 操作符重载 eg:复数x+yi +4i (+2i) + (+4i) = +6i 双目操作符(L # R) 1.1 运算类的双目操作符:+ - * / -->左右操作数可以是左值也可以是右值 ...
- C++中操作符重载的概念
1,下面的复数解决方案是否可行? 1,代码示例: class Comples { public: int a; int b; }; int main() { Complex c1 = {, }; Co ...
- C#中如何利用操作符重载和转换操作符
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
随机推荐
- CXF+Spring+JAXB+Json构建Restful服务
话不多说,先看详细的样例: 文件文件夹结构: web.xml <?xml version="1.0" encoding="UTF-8"? > < ...
- python标准库介绍——14 gc 模块详解
==gc 模块== (可选, 2.0 及以后版本) ``gc`` 模块提供了到内建循环垃圾收集器的接口. Python 使用引用记数来跟踪什么时候销毁一个对象; 一个对象的最后一个引用一旦消失, 这个 ...
- unity physics joint
除了unity文档(有点儿过于简略)之外,可以参考一下PhysX文档: http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/ ...
- cocos2dx 3.3将坐标由父空间转化到局部空间
设在node的父空间内有一点p,要求其转化到node局部空间后的坐标p_local,代码如下: node->getNodeToParentTransform();//in order node- ...
- mysql不重启修改参数变量
分享下mysql不重启的情况下修改参数变量的方法. 通常来说,更新mysql配置my.cnf需要重启mysql才能生效,但是有些时候mysql在线上,不一定允许你重启,这时候应该怎么办呢? 例子: m ...
- 无线路由器硬件配置參数 NetGear篇
NetGear WNDR4500(号称地球上最强的无线路由器) 450Mbps+450Mbps 京东¥1399 0MHz.配备了128MB的内存和128MB的闪存,再以 ...
- [转贴]Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
看了opengles有一段时间了,算是了解了一下下.然后,就在基本要决定还是回归cocos2dx 3.2的,看了这篇好文章,欣喜转之~ 推荐看原帖: Cocos2d-x3.2与OpenGL渲染总结(一 ...
- C++ 11 Lambda表达式、auto、function、bind、final、override
接触了cocos2dx 3.0,就必须得看C++ 11了.有分享过帖子:[转帖]漫话C++0x(四) —- function, bind和lambda.其实最后的Lambda没太怎么看懂. 看不懂没关 ...
- 我对C++的一些疑问
我对C++的一些疑问,最近使用C++,总感觉有些东西自己没有抓住,也可能是自己基础学的不是很扎实,所以对一些基本的东西理解不够透彻导致的.因为自己在学校也学过C#和java,C#它是一个完全的面向对象 ...
- rzsz安装【转】
环境:CentOS 发生情况:需要安装工具:szrz 工具进行 windows 和linux传文件 安装方式:从网上其他教程找的所以就按照如下方式操作 1. 下载软件 rzsz-3.34.tar.gz ...