简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:Android14之深入理解模板类
2.介绍
- C++模板类是C++编程语言中的一种特性,它允许程序员定义能够处理任何类型数据的类。模板类是一种泛型编程的工具,可以在不牺牲性能的情况下提供类型安全的代码。在C++中,模板类可以用于创建可重用的、通用的代码,从而提高程序的可维护性和可扩展性。
- 模板类的基本原理是模板参数。模板参数是一种特殊的参数,它在类定义时使用,用于指定类可以操作的数据类型。程序员可以在声明类时使用模板参数,然后在创建类的实例时指定具体的类型。这样,模板类就可以根据传入的类型参数生成相应的类实例,从而实现对不同类型数据的处理。
- 模板类的基本语法如下:
template <class T>
class ClassName {
public:
// 类成员函数和数据成员
};
- 其中,
<class T>
表示模板参数,T
是一个占位符,表示传入的具体类型。ClassName
是类的名称,它可以是任何有效的C++类名。 - 模板类具有以下特点:
- 类型安全:模板类通过编译时类型检查确保类型安全。在创建模板类的实例时,编译器会检查模板参数是否合法,并生成相应的类实例。这可以防止在运行时出现类型错误。
- 泛型编程:模板类允许程序员编写通用的代码,可以处理多种数据类型。这有助于减少代码冗余,提高程序的可维护性和可扩展性。
- 性能:模板类在编译时生成具体的类实例,因此在运行时不会产生额外的性能开销。模板类的设计目标是在不牺牲性能的情况下提供类型安全的代码。
- 兼容性:模板类可以与常规类混合使用。程序员可以在同一个项目中同时使用模板类和非模板类,以满足不同的编程需求。
- 继承:模板类可以被继承。子类可以继承模板类的特性,并可以添加新的功能或修改现有功能。这使得模板类可以作为基类,为子类提供通用的功能。
- 举个例子,以下是一个简单的模板类,用于计算两个数值的和的平方:
template <class T>
class SumSquare {
public:
T operator()(T a, T b) {
return (a + b) * (a + b);
}
};
- 在这个例子中,
SumSquare
是一个模板类,它接受两个类型为T
的参数a
和b
,并返回它们的和的平方。程序员可以在创建SumSquare
的实例时指定具体的类型,例如:
int result = SumSquare<int>(3, 4); // 创建 SumSquare<int> 的实例,计算 3 + 4 的和的平方
double result = SumSquare<double>(3.0, 4.0); // 创建 SumSquare<double> 的实例,计算 3.0 + 4.0 的和的平方
- 总结起来,C++模板类是一种强大的编程工具,它提供了类型安全、泛型编程、性能和兼容性等优点。通过使用模板类,程序员可以编写可重用、通用的代码,提高程序的可维护性和可扩展性。
3.代码实例
<1>.Android智能指针sp用法实例
#include <utils/Log.h>
#include <string>
#include <iostream>
#include <utils/RefBase.h>
using namespace std;
class BB : public android::RefBase {
public:
BB() {}
};
int main() {
//v1.0
android::sp<BB> bb = NULL;
//bb.get() = NULL
printf("xxx--------------->%s, %s(), line = %d, bb.get() = %p\n",__FILE__,__FUNCTION__,__LINE__,bb.get());
//v2.0
android::sp<BB> b1 = new BB();
printf("xxx--------------->%s, %s(), line = %d, b1.get() = %p\n",__FILE__,__FUNCTION__,__LINE__,b1.get());
return 0;
}
v1.0传入空指针
v2.0传入实际类对象
<2>.自定义模板类实现(深入理解Android模板类sp的实现)
#include <memory>
#include <iostream>
using namespace std;
template <typename T>
class Base {
public:
//1.模板类构造函数,传给模板类成员变量m_ptr.
Base(T *other) : m_ptr(other){
}
//2.返回真正类的对象.
T* get(){
printf("xxx--------------->%s(), line = %d, m_ptr = %p\n",__FUNCTION__,__LINE__,m_ptr);
return m_ptr;
}
private:
T *m_ptr;
};
class BB : public Base<BB>{
public:
//v1.0 不能使用默认构造函数,因为需要显示告诉Base模板类自己需要的类型,如果使用默认构造函数,它无法正确初始化基类,它不知道传递什么参数给基类的构造函数Base.
//BB(){}
//v2.0 传this,尚未完全构造的BB对象地址,this指针总是指向有效的BB对象,基类Base只是简单地存储了这个指针,并不进行任何依赖于对象完全构造的操作.
BB() : Base<BB>(this){}
void print(){
printf("xxx--------------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
int main(void) {
//v1.0: 模板类Base<BB>接收空指针NULL.
Base<BB> b1 = nullptr;
//or
//Base<BB> b1 = Base<BB>(nullptr);
cout << "b1.get() = " << b1.get() << endl;
//v2.0: 将BB类实例化对象传入模板类Base<BB>.
Base<BB> b2 = new BB();
//Or
//Base<BB> b2 = Base<BB>(new BB);
cout << "b2.get() = " << b2.get() << endl;
//1.b2:表示模板类Base<BB>对象
//2.b2.get():表示模板类存放的BB实际类的指针对象.
//3.b2.get()->print():表示调用模板类中BB类的成员函数print().
b2.get()->print();
//4.free BB实际对象.
delete b2.get();
//错误:BB类型的对象,而不是一个指针,不能使用delete来释放它.
//delete b2;
return 0;
}
注释已经很详细,就不多说了。