借助基类指针调用虚接口的方式,即多态,可以实现业务层仅感知到基础类型及接口定义,分发执行子类对象覆写实现的效果。但对于非同一继承层次内的类型,接口调用则只能通过针对每个类型定义适配类的方式来实现,但每增一个子类都要有新增适配类,则会导致类数量的膨胀。而模板更能适配这类场景。
#include <string>
#include <memory>
#include <iostream>
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<typename T>
ThingWithToString(const T& obj)
: inner_(std::make_unique<Holder<T> >(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<HolderBase> clone() const = 0;
};
// HolderBase的子类与类型形参直接关联,明确感知类型。同时实现父类的纯虚接口。
template<typename T>
struct Holder : public HolderBase {
Holder(const T& obj)
: obj_(obj)
{
}
std::string toString() const override
{
return obj_.toString();
}
std::unique_ptr<HolderBase> clone() const override
{
return std::make_unique<Holder<T> >(obj_);
}
T obj_;
};
std::unique_ptr<HolderBase> 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;
}
876

被折叠的 条评论
为什么被折叠?



