前言
最后的实例利用一个模板类来实现类内与类外重载输出运算符。
其他运算符的重载类似。
如果不需要模板,去掉模板即可。
一、类内与类外重载运算符
1.类内重载与类外重载的区别
1.1类外重载一般需要类内声明友元,详见2.
1.2类内实现,调用的时候需要用对象调用,参数列表只包含一个ostream类引用。
1.3类内,作为成员函数,所以没有友元声明一说。也直接可以访问私有成员。
2.类外重载为什么需要友元
类外实现重载,需要在类内声明友元,才能使得重载函数中能访问到类中private 的成员。其中template 声明了这个也是一个模板函数。
template<typename T>
friend ostream &operator<<(ostream &os, MyQueue<T> temp);
关于模板类
C++模板类与模板函数实现不会的可以看这个:模板函数、模板类
3.类内重载与类外重载,调用的区别
类外重载调用方式:与常用一致
cout << my_queue << endl;
类外重载调用方式:与常用相反。函数内直接用this 用作调用的对象。
my_queue.operator<<(cout);//类内重载调用方法1
my_queue2<<cout;//类内重载调用方法2
二、实例
重点看重载运算符:
类内实现与类外友元实现的区别;
每种的调用区别。
// ConsoleApplication2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<string.h>
#include<malloc.h>
#include<string>
#include<vector>
#include<math.h>
#include<algorithm>
#include<math.h>
#include <unordered_set>
#include<stack>
//#include<queue>
using namespace std;
template<typename TT>
class MyQueue {
private:
stack<TT> mystack;
public:
/** Initialize your data structure here. */
MyQueue() {
}
void operator<<(ostream &os) {
//this->mystack
MyQueue<TT> temp_mystack = *this;
os << "operator<< in class : ";
while (!temp_mystack.mystack.empty())
{
os << "" << temp_mystack.mystack.top();
temp_mystack.mystack.pop();
}
os << endl;
//return os;
}
template<typename T>
friend ostream &operator<<(ostream &os, MyQueue<T> temp);
/** Push element x to the back of queue. */
void push(TT x) {
stack<TT> mystack2;
while (!mystack.empty())
{
mystack2.push(mystack.top());
mystack.pop();
}
mystack.push(x);
while (!mystack2.empty())
{
mystack.push(mystack2.top());
mystack2.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
TT pop() {
TT temp = mystack.top();
mystack.pop();
return temp;
}
/** Get the front element. */
TT peek() {
return mystack.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return mystack.empty();
}
};
template<typename T>
ostream &operator<<(ostream &os, MyQueue<T> temp) {
os << "operator<< out of class : ";
while (!temp.mystack.empty())
{
os << "" << temp.mystack.top();
temp.mystack.pop();
}
return os;
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
void main()
{
MyQueue<string> my_queue;
my_queue.push("he");
my_queue.push("llo");
cout << my_queue << endl;//类外重载调用方法
my_queue.push(" word");
my_queue.push(" ss");
my_queue.operator<<(cout);//类内重载调用方法1
cout << my_queue << endl;
MyQueue<int> my_queue2;
my_queue2.push(1);
my_queue2.push(2);
cout <<my_queue2 << endl;
my_queue2.push(3);
my_queue2.push(4);
my_queue2<<cout;//类内重载调用方法2
cout << my_queue2 << endl;
}
实现效果:
圈出来了类内实现打印出来的,剩下的就是类外友元实现打印的。
参考
https://blog.youkuaiyun.com/weixin_44503157/article/details/116495743?spm=1001.2014.3001.5501