简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
文章来源:https://www.toymoban.com/news/detail-516998.html
1.前言
本篇目的:理解模板类指向子类对象应用。文章来源地址https://www.toymoban.com/news/detail-516998.html
2.应用实例
<1>.v1.0 基础版
#include<iostream>
using namespace std;
template<typename SERVICE>
class BaseA{
public:
BaseA(){
//printf("xxx--------->%s(), line = %d, i = %s\n",__FUNCTION__,__LINE__,SERVICE::getServiceName());
}
virtual void test(int i) = 0;//纯虚函数,子类必须实现.
};
class Parent{
public:
Parent(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
//Derived继承自类模板BaseA<任意类型>.将子类的类型传参给模板类,在模板类可以调用子类Derived的getServiceName()和value
class Derived: public BaseA<Derived>{
friend class BaseA<Derived>;
public:
void test(int i){
printf("xxx--------->%s(), line = %d, i = %d\n",__FUNCTION__,__LINE__,i);
}
static const char *getServiceName() { return "media.audio_policy"; }
int value = 100;
};
int main(){
//1.子类指向子类对象
Derived *dr = new Derived();
dr->test(777);
printf("xxx--------->%s(), line = %d, value = %d\n",__FUNCTION__,__LINE__,dr->value);
//2.父类指向子类对象
BaseA<Derived> *b = new Derived;
b->test(999);
//printf("xxx--------->%s(), line = %d, value = %d\n",__FUNCTION__,__LINE__,b->value);//error
}
<2>.v2.0 升级版
#include<iostream>
using namespace std;
template<typename SERVICE>
class BaseA{
public:
BaseA(){
printf("xxx--------->%s(), line = %d, i = %s\n",__FUNCTION__,__LINE__,SERVICE::getName());
}
virtual void test(int i) = 0;//纯虚函数,子类必须实现.
};
class Parent{
public:
Parent(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
static const char *getName() { return "Hello Test."; }
};
class Derived: public BaseA<Parent>{
friend class BaseA<Parent>;
public:
void test(int i){
printf("xxx--------->%s(), line = %d, i = %d\n",__FUNCTION__,__LINE__,i);
}
static const char *getServiceName() { return "media.audio_policy"; }
int value = 100;
};
int main(){
//1.父类BaseA<Parent>模板类指向子类对象Derived
BaseA<Parent> *b = new Derived();
b->test(999);
}
<3>.v3.0 仿Refbase例子
#include <iostream>
#include <string>
using namespace std;
class RefBase{
public:
RefBase(){
printf("xxx---------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
class BpRefBase : public RefBase{
public:
BpRefBase(){
printf("xxx---------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
template <typename INTERFACE>
class BpInterface : public INTERFACE, BpRefBase{
public:
BpInterface(INTERFACE* ptr) : mPtr(ptr) {}
void print(string cmd) {
printf("xxx---------->%s(), line = %d, type(class) = %s\n",__FUNCTION__,__LINE__,typeid(INTERFACE).name());
}
INTERFACE *get(){
return mPtr;
}
void takePicture() override {
printf("xxx---------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
INTERFACE* mPtr;
};
class ICameraService {
public:
virtual void takePicture() = 0;
};
class CameraService : public ICameraService {
public:
void takePicture() override {
printf("xxx---------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
int main() {
#if 0
//第一种方式
/*
CameraService 类是 ICameraService 接口的子类,而 BpInterface 类是一个模板类,它的模板参数是 ICameraService。在这个语句中,我们创建了一个 CameraService 类的对象,并将其赋值给了 BpInterface<ICameraService> 类型的变量 bpInterface。
由于 CameraService 是 ICameraService 的子类,所以它满足了 BpInterface 类对模板参数的要求。因此,我们可以将 CameraService 对象赋值给 BpInterface<ICameraService> 类型的变量。
这种用子类对象赋值给父类指针或引用的行为被称为多态。在多态中,我们可以使用父类的指针或引用来操作子类的对象,这样可以实现代码的灵活性和可扩展性。
*/
//1.父类ICameraService指向子类对象CameraService
BpInterface<ICameraService> bpInterface = new CameraService();
//2.调用BpInterface类的成员函数print()
bpInterface.print("123");
//3.通过BpInterface类的mPtr指针,调用CameraService类重写的纯虚函数takePicture().
bpInterface.get()->takePicture();
#else
//第二种方式
ICameraService *cameraService = new CameraService();
BpInterface<ICameraService> *bpInterface = new BpInterface<ICameraService>(cameraService);
bpInterface->print("123");
bpInterface->get()->takePicture();
#endif
return 0;
}
<4>.v4.0 父类指针指向子类对象区别
(1).
#include<iostream>
#include <typeinfo>
using namespace std;
template<typename SERVICE>
class BaseA{
public:
BaseA(){
mptr = new SERVICE;
}
void test(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
SERVICE *get(){
return mptr;
}
SERVICE *mptr;
};
class Parent{
public:
static const char *getName() { return "media.audio"; }
};
class Derived: public BaseA<Parent>{
friend class BaseA<Parent>;
public:
Derived(){}
};
int main(){
//1.父类BaseA<Parent>模板类指向子类对象Derived
BaseA<Parent> *b = new Derived();
//2.调用类模板BaseA的成成员函数test.
b->test();
//3.调用传入模板类的Parent的成员函数getName.
const char *name = b->get()->getName();
printf("xxx--------->%s(), line = %d,name = %s\n",__FUNCTION__,__LINE__,name);
}
(2)
#include<iostream>
#include <typeinfo>
using namespace std;
#define NTD
template<typename SERVICE>
class BaseA{
public:
BaseA(SERVICE *ptr) : mPtr(ptr){
printf("xxx--------->line = %d, type = %s, name = %s\n",__LINE__,typeid(SERVICE).name(),SERVICE::getName());
}
SERVICE *get(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
return mPtr;
}
void test(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
SERVICE *mPtr;
};
class Parent{
public:
static const char *getName() { return "media.audio"; }
int value = 100;
};
class Derived: public Parent{
public:
int count = 200;
};
int main(){
//第一种方式:
//1.父类BaseA<Parent>模板类指向子类对象Derived
BaseA<Parent> b = new Derived();
/*
将Parent类传入类模板BaseA,接着进入BaseA模板类构造函数初始化列表,进行初始化,将类Parent指针对象ptr传递给传给模板类的BaseA的成员变量mPtr,模板类b,因为Device继承自Parent类,将Device对象赋值给b。
子类对象赋值给父类指针或引用的行为被称为多态。在多态中,我们可以使用父类的指针或引用来操作子类的对象
*/
//2.调用类模板BaseA的成成员函数test.
b.test();
//3.调用传入模板类的Parent的成员函数getName.
const char *name = b.mPtr->getName();
printf("xxx--------->%s(), line = %d,name = %s\n",__FUNCTION__,__LINE__,name);
//4.
int val = b.get()->value;
printf("xxx--------->%s(), line = %d,val = %d\n",__FUNCTION__,__LINE__,val);
//第二种方式:
BaseA<Parent> *bb = new BaseA<Parent>(new Derived());
bb->test();
const char *name_01 = bb->mPtr->getName();
}
<5>.v5.0 仿CameraService::instantiate()例子
#include <iostream>
using namespace std;
template<typename SERVICE>
class BinderService{
public:
static void instantiate() {
printf("xxx-------->line = %d, service_name = '%s'\n",__LINE__,SERVICE::getServiceName());
SERVICE *cm = new SERVICE();
printf("xxx-------->line = %d, count = %d, type(name) = %s\n",__LINE__,cm->count,typeid(SERVICE).name());
}
};
class CameraService : public BinderService<CameraService>{
friend class BinderService<CameraService>;
static char const* getServiceName() { return "media.camera"; }
int count = 220;
};
int main(){
//way01:
CameraService::instantiate();
//way02:
CameraService *cm = new CameraService;
cm->instantiate();
}
到了这里,关于C++之模板类指向子类对象(一百四十六)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!