最近在搞FFmpeg 音视频开发,后面大量涉及音视频图形等界面开发(比如视频播放器), 利用C语言也可以实现 ,但相对麻烦,在这方面C++会方便很多,记得上一次学C++还是在大二的时候了, 刚好也算趁着这一次机会,把C++ 的知识全部重新捡起来巩固一遍, 也算逼自已一把,实现由C转C++,后面写代码、写算法就全使用C++ 来实现了。
有关C++ 的学习,打算专门花两天时间全部过一遍,因为有基础,所以我学习时都是跳着学,这样快些 参考视频教程:《C++教程从0到1入门编程》
第一天 10月4号 将C++基础全部过了一遍 (面向对象), 包括C++中的数据类型、数组、指针、类和对象等,和C大同小异,这里就不多说了。
第二天 10月5号 将C++更高级一些编程过一遍(泛型编程思想),这些功能很多都是C中没有的,用起来确实会很方便。
好了,前言就到这里吧,我们开始学习。
有关知识点 ,我全部以注释的形式写在代码中,结合代码方便理解运用
函数模板声明: template <typename T>,T 是一个通用数据类型,将数据类型参数化,利高代码的复用性 typename 也可以写成 template<class T>,没什么差别
函数模板使用有两种方法: (1)方法一:利用编译器自动推导(必须推导出一致的数据类型 T 才可以使用) (2)方法二:显示指定类型 T,在显示指定类型后,转参如果不是当前类型,则会自动发生隐式类型转换。
示例如下:
#include <iostream> using namespace std; // 声明一个函数模板,告诉编译器后面代码中紧跟着的T不要的报错 // T 是一个通用数据类型,将数据类型参数化,利高代码的复用性 template<typename T> // 交换两个数据,数据类型为 T,数据传递方式为引用 void Swap(T &a, T &b){ T temp = a; a = b; b = temp; } int main(){ int a = 10, b = 20; cout << "初始值: a = " << a << " b = " << b << endl; // 利用函数模板交换数据 // 方法一:利用编译器自动推导 cout << "方法一、利用编译器自动推导 T 的数据类型" << endl; Swap(a, b); cout << "交换后: a = " << a << " b = " << b << endl << endl; // 方法二:显示指定类型 T cout << "方法二 、显示指定类型 T" << endl; Swap<int>(a, b); // 指定T 的数据类型为 T cout << "交换后: a = " << a << " b = " << b << endl; system("pause"); return 0; }当普通函数,与 模板函数重名时,如果要强制调用模板函数,需要使用增加空模板参数列表来实现:Sort_array<>(c_arr, num);
代码示例如下, 如果不使用Sort_array<>(c_arr, num);来调用, 默认会调用普通函数Sort_array,从而报程序错误(函数未实现), 使用空模板参数列表后,正常运行,调用的是模板函数。
#include <iostream> using namespace std; void Sort_array(char arr[], int len); // 实现通用的对数组从小到大排序的函数 template <class T> void Sort_array(T arr[], int len) { // 选择排序 for (int i = 0; i < len; i++) // 外循环 { int max = i; for (int j = i + 1; j < len; j++) // 内循环 { if (arr[max] > arr[j]) { // 比较出最小值索引 max = j; } } if (max != i) { // 交换元素 T temp = arr[i]; arr[i] = arr[max]; arr[max] = temp; } } } template<class T> void print_array(T arr[], int len) { for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout << endl << endl; } int main() { { char c_arr[] = "zyxwvutsrqponmlkjihgfedcba"; int num = sizeof(c_arr) / sizeof(char) - 1; // 对数组进行从小到大排序 Sort_array<>(c_arr, num); print_array(c_arr, num); // 打印数组 } { float f_arr[] = { 10.1,9.1,8.1,7.1,6.1,5.1,4.1,3.1,2.1,1.1 }; int num = sizeof(f_arr) / sizeof(float); // 对数组进行从小到大排序 Sort_array<>(f_arr, num); print_array(f_arr, num); // 打印数组 } system("pause"); return 0; }示例如下:
template <class T> void fun(T &a, T &b ){ XXX; } template <class T> void fun(T &a, T &b , T &c){ XXX; } template <class T> void fun(T &a, T &b , T &c, int d){ XXX; }模板并不是万能的,有些特这下的数据类型,需要用具体化方式来实现(比如一个 Class Person 对象)。 示例: template<> bool Compare(Person& a, Person& b)
代码如下:
#include <iostream> #include <string> using namespace std; class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } string m_Name; int m_Age; }; template<class T> bool Compare(T& a, T& b) { if (a == b) return true; return false; } // 虽然可能通过重载 operate== 来实现,但这个比较麻烦 // 此处,利用具体化Person 的版本实现代码,具体化模板函数优先调用 template<> bool Compare(Person& a, Person& b) { if (a.m_Name == b.m_Name && a.m_Age == b.m_Age) return true; else return false; } int main() { Person p1("Tom", 10); Person p2("Tony", 12); if (Compare(p1, p2)) cout << "p1 == p2" << endl; else cout << "p1 != p2" << endl; system("pause"); return 0; }函数模板是在模板后面写一个函数,类模板就是下在模板后写一个类,其他的没什么区别。
类型板在可以指定N 个所需的可变数据类型,如下T1 、T2
template<typename T1, typename T2> 或 template<class T1, typename T2> 类 类注意,类模板中不能自动推导数据类型,必须显示指定数据类型,但在模板参数列表中可以使用默认参数。
类模板分文件编写时,有如下两种方式:
类模板定义代码保存为.h,类模板函数实现代码保存为 .cpp,此时需要 #include "xxx.cpp"将类模板定义代码 和类模板函数实现代码 保存在一起,名为 xxx.hpp,此时需要包含 #include "xxx.hpp"