本文共 2260 字,大约阅读时间需要 7 分钟。
借助基类指针调用虚接口的方式,即多态,可以实现业务层仅感知到基础类型及接口定义,分发执行子类对象覆写实现的效果。但对于非同一继承层次内的类型,接口调用则只能通过针对每个类型定义适配类的方式来实现,但每增一个子类都要有新增适配类,则会导致类数量的膨胀。而模板更能适配这类场景。
#include#include #include class IAnimal { public: IAnimal() {} virtual ~IAnimal() {} virtual void makeSound() const = 0;};class Dog : public IAnimal { public: Dog() {} virtual ~Dog() override {} virtual void makeSound() const override { std::cout << "woof" << std::endl; } std::string toString() const { return "Dog"; }};class Cat : public IAnimal { public: Cat() {} virtual ~Cat() override {} virtual void makeSound() const override { std::cout << "meow" << std::endl; } std::string toString() const { return "Cat"; }};class Robot { public: std::string toString() const { return "Robot"; }};using namespace std;// 业务与非模板类型 HolderBase有关联依赖,HolderBase中不体现类型形参class ThingWithToString {public: template ThingWithToString(const T& obj) : inner_(std::make_unique >(obj)) { } ThingWithToString(const ThingWithToString& that) : inner_(that.inner_->clone()) { } ThingWithToString& operator=(const ThingWithToString& that) { if (this != &that) { inner_ = that.inner_->clone(); } return *this; } std::string toString() const { return inner_->toString(); }private: struct HolderBase { virtual ~HolderBase() { } virtual std::string toString() const = 0; virtual std::unique_ptr clone() const = 0; };// HolderBase的子类与类型形参直接关联,明确感知类型。同时实现父类的纯虚接口。 template struct Holder : public HolderBase { Holder(const T& obj) : obj_(obj) { } std::string toString() const override { return obj_.toString(); } std::unique_ptr clone() const override { return std::make_unique >(obj_); } T obj_; }; std::unique_ptr inner_;}; // Cat、Dog与Robot属不同类别,但都有一致的及接口约定(tostring),这是模板适用的前提。 ThingWithToString getThingWithToString(int which){ switch (which) { case 0: return ThingWithToString(Dog()); case 1: return ThingWithToString(Robot()); default: throw std::runtime_error("Unknown object type"); }} int main(){ int which = 1; std::cin >> which; ThingWithToString object = getThingWithToString(which); std::cout << object.toString() << std::endl; return 0;}
转载地址:http://rscws.baihongyu.com/