项目中一般会遇到成对出现的操作,例如new和delete,malloc和free,或者一切自定义的操作形之如Lock和UnLock的操作。
对于new,STL里面有auto_ptr,有时为每个成对操作的对象都实现一个类似于auto_ptr的又显得得不偿失,且有违C++复用的宗旨。
下面给的代码是上述问题的一个解决方案:
class A
{
public:
void lock()
{
printf("A::lock\n");
}
void unlock()
{
printf("A::unlock\n");
}
};
class B
{
public:
void Before()
{
printf("B::Before\n");
}
void After()
{
printf("B::After\n");
}
};
class C
{
public:
};
template<class T>
class Guard_Adapter_T
{
public:
Guard_Adapter_T(T& d) : d_(d)
{
Enter();
}
~Guard_Adapter_T()
{
Leave();
}
void Enter();
void Leave();
private:
T& d_;
};
template<>
void Guard_Adapter_T<A>::Enter()
{
d_.lock();
}
template<>
void Guard_Adapter_T<A>::Leave()
{
d_.unlock();
}
template<>
void Guard_Adapter_T<B>::Enter()
{
d_.Before();
}
template<>
void Guard_Adapter_T<B>::Leave()
{
d_.After();
}
int _tmain(int argc, _TCHAR* argv[])
{
A a;
Guard_Adapter_T<A> d1(a);
B b;
Guard_Adapter_T<B> d2(b);
// //无法解析的外部符号
// C c;
// GUARD_1<C> d3(c);
return 0;
}
学术点的叫法是 “外部多态(External-Polymorphism)”
外部多态 的目的是:
允许没有继承关系并且/或者没有虚函数的C++类能够被多态的使用。这些没有关系的类可以被使用它们的软件以统一的方式使用
动机:
不同来源的C++类一起工作是困难的。应用程序经常需要这些类“体现”出某些公共的行为,但会被这些类已有的设计所限制。如果只是类接口需要适配,一个很明显解决方案是使用适配器(Adapter)或者装饰(Decorator)[1]这样的对象结构模式。有时会遇到更复杂的需求,比如既需要改变下边的接口也需要改变实现。在这种情况下,可能需要这些类的行为好像它们有公共的基类一样。
例如,试想我们正在调试一个由来自不同的库的C++类构建起来的应用程序,它能够方便的将任意对象的内部状态以人能够读懂的格式输出到文件或者显示在控制台。它甚至能够方便将所有存在的类实例放到一个集合里并且遍历这个集合让每个实例输出自己的信息。
因为集合中的元素都是同一类的,要维护一个集合就要求必须存在一个公共的基类。但是这些类早已经设计、实现并且开始使用了,并且我们也不能选择通过修改继承树并引入一个公共基类的方式—我们可能不能访问源代码。另外,像C++这样的OO语言中的类属于具体数据类型(concrete date type)[2],它需要精确的存储格局,不能包括一些隐藏的指针(例如C++的虚函数表指针)。用一个公共的多态的基类重新实现这些类是不可行的。
因此,使不相关的类体现出公共行为的解决方案必须满足以下强制约束:
1、 空间效率—方案不能影响已经存在对象的存储格局。特别是没有虚函数的类(例如,具体数据类型)不能被强制加入一个虚函数表指针。
2、 多态—所有库的对象必须可以使用统一的透明的方式访问,特别是当新类加到系统中是,我们不需要修改已经存在的代码。
参照:
http://blog.youkuaiyun.com/waitan/article/details/1537983