C++模板与运算符重载实战技巧

📅 2026/6/25 18:53:16
C++模板与运算符重载实战技巧
例题一格式化输入输出函数模板的语法和类模板写法有区别容易记混格式手写排序算法冒泡 / 插入排序的边界容易写错自定义类 运算符重载Point 类要重载做比较、重载做输出格式化输入输出点的输入是(x,y)格式要处理括号、逗号编写一个对n个元素的数组升序排序的函数模板mysort其中元素类型可以是基本数据类型,也可以是点对象(按点到原点的距离比较)。要求不能用C提供的sort函数模板输入第一行输入测试次数每次测试输入二行第1行先输入一个大写字母表示数组类型I表示整数类型S表示字符串型D表示双精度数类型P表示点最后输入n表示数组长度。第2行输入n个数据。输出每次测试输出一行排序后的结果#include iostream #include string #include iomanip using namespace std; // 通用冒泡排序函数模板 templatetypename T void mysort(T arr[], int n) { for(int i 0; i n-1; i) { bool flag false; for(int j 0; j n-1-i; j) { if(arr[j] arr[j1]) { T temp arr[j]; arr[j] arr[j1]; arr[j1] temp; flag true; } } if(!flag) break; } } // 点类重载比较运算符供排序使用 class Point { double x, y; public: Point() : x(0), y(0) {} Point(double x, double y) : x(x), y(y) {} bool operator(const Point other) const { double dist1 x*x y*y; double dist2 other.x*other.x other.y*other.y; return dist1 dist2; } bool operator(const Point other) const { return other *this; } friend ostream operator(ostream out, const Point p) { ios old_fmt(NULL);//1.创建一个格式存档对象 //cout的所有格式设置小数位数对齐方式进制都存在ios状态里面 //old_fmt存之前的格式 old_fmt.copyfmt(out);//2.把当前cout的所有格式设置完整保存下来 //把传进来的流对象 out也就是调用时的 cout当前的全部格式设置完整复制到 old_fmt 里 out fixed setprecision(1); out ( p.x , p.y );//设置的新格式 out.copyfmt(old_fmt);//把保存的旧格式还原回去 return out; }//如果不这样做就会改变全局输出格式导致其他类型数据的输出格式也随之变化 friend istream operator(istream in, Point p) { in p.x p.y; return in; } }; templatetypename T void printArr(T arr[], int n) { for(int i 0; i n; i) { if(i ! 0) cout ; cout arr[i]; } cout endl; } int main() { int t; cin t; while(t--) { char type; int n; cin type n; if(type I) { int* arr new int[n]; for(int i 0; i n; i) cin arr[i]; mysort(arr, n); printArr(arr, n); delete[] arr; } else if(type D) { double* arr new double[n]; for(int i 0; i n; i) cin arr[i]; mysort(arr, n); printArr(arr, n); delete[] arr; } else if(type S) { string* arr new string[n]; for(int i 0; i n; i) cin arr[i]; mysort(arr, n); printArr(arr, n); delete[] arr; } else if(type P) { Point* arr new Point[n]; for(int i 0; i n; i) cin arr[i]; mysort(arr, n); printArr(arr, n); delete[] arr; } } return 0; }例题二类模板 模板特化Data类不只是存数据它把输入读取、区间越界裁剪、排序、格式化输出一整套业务流程全打包进了类里。#include bits/stdc.h #include iomanip using namespace std; templatetypename T class Data { vectorT data; public: Data(int n) : data(n) { for(int i 0; i n; i) { cin data[i]; } } void sortRange(int beg, int end) { int left max(beg, 0); int right min(end, (int)data.size()); if(left right) return; sort(data.begin() left, data.begin() right); } void show() { cout [; for(int i 0; i data.size(); i) { if(i ! 0) cout , ; cout data[i]; } cout ] endl; } }; template void Datafloat::show() { cout [ fixed setprecision(1); for(int i 0; i data.size(); i) { if(i ! 0) cout , ; cout data[i]; } cout ] endl; } int main() { int t; cin t; while(t--) { string type; int n, x, y; char c; cin type n; cin c; cin x; cin c; cin y; cin c; cin c; if(type int) { Dataint d(n); d.sortRange(x, y); d.show(); } else if(type string) { Datastring d(n); d.sortRange(x, y); d.show(); } else if(type float) { Datafloat d(n); d.sortRange(x, y); d.show(); } } return 0; }template空尖括号是全特化的标志模板参数已经全部指定为具体类型没有占位符了Datafloat::show()明确说明这是给T float版本的Data类专属的show函数