什么是在比较两种技术的优点/缺点是什么? 更重要的是:为什么以及何时应该被一个比其他使用? 难道仅仅是一种个人品位/偏好的事?
要尽我的能力,我还没有发现在另一个帖子里明确地解决我的问题。 关于所实际使用的多态性和/或类型擦除的许多问题,下面似乎是最接近的,至少看起来是这样,但它并没有真正解决我的问题之一:
C ++ - &CRTP。 类型擦除VS多态性
请注意,我很好地理解这两种技术。 为此,我提供了一个简单,独立的,工作下面的例子,我很高兴地取出,如果觉得没有必要。 然而,例如应该澄清一下这两种技术对于我的问题的意思。 我没有兴趣讨论的命名。 另外,我知道和编译期运行时多态性之间的差异,但我不认为这是相关的问题。 请注意,我的兴趣是少性能差异,但如果有任何。 但是,如果有一个或基于绩效的另外一个惊人的说法,我很好奇阅读。 我特别想听听具体的例子(没有代码),将真的只能用这两种方法的工作之一。
寻找下面的例子中,一个主要的区别是内存管理,这对于多态保留在用户侧,以及用于类型擦除被整齐地卷起需要一些引用计数(或增压)。 话虽如此,这取决于使用情景,这种情况可能是多态性,例如通过使用智能指针与向量改善(?),但对于任意情况下,这很可能变成是不切实际的(?)。 另一方面,可能有利于类型擦除的,可能是一个通用接口的独立性,但到底为什么会是这样一个优势(?)。
如下面给出的代码通过简单地把所有的下面的代码块中的到单个源文件进行了测试用的VisualStudio MS 2008(编译&运行)。 还应该用gcc编译的Linux,或者我希望如此/假设,因为我看不出有什么理由,为什么不(?):-)我已经分手/分在这里的代码清晰。
这些报头文件应该是足够的,正确的(?)。
#include <iostream>
#include <vector>
#include <string>
简单的引用计数,以避免刺激(或其他方式)的依赖。 这个类仅在下面类型擦除-实施例中使用。
class RefCount
{
RefCount( const RefCount& );
RefCount& operator= ( const RefCount& );
int m_refCount;
public:
RefCount() : m_refCount(1) {}
void Increment() { ++m_refCount; }
int Decrement() { return --m_refCount; }
};
这是简单的类型擦除示例/图示。 它被复制和部分来自下面的文章进行修改。 主要是我试图让它清晰和简单越好。 http://www.cplusplus.com/articles/oz18T05o/
class Object {
struct ObjectInterface {
virtual ~ObjectInterface() {}
virtual std::string GetSomeText() const = 0;
};
template< typename T > struct ObjectModel : ObjectInterface {
ObjectModel( const T& t ) : m_object( t ) {}
virtual ~ObjectModel() {}
virtual std::string GetSomeText() const { return m_object.GetSomeText(); }
T m_object;
};
void DecrementRefCount() {
if( mp_refCount->Decrement()==0 ) {
delete mp_refCount; delete mp_objectInterface;
mp_refCount = NULL; mp_objectInterface = NULL;
}
}
Object& operator= ( const Object& );
ObjectInterface *mp_objectInterface;
RefCount *mp_refCount;
public:
template< typename T > Object( const T& obj )
: mp_objectInterface( new ObjectModel<T>( obj ) ), mp_refCount( new RefCount ) {}
~Object() { DecrementRefCount(); }
std::string GetSomeText() const { return mp_objectInterface->GetSomeText(); }
Object( const Object &obj ) {
obj.mp_refCount->Increment(); mp_refCount = obj.mp_refCount;
mp_objectInterface = obj.mp_objectInterface;
}
};
struct MyObject1 { std::string GetSomeText() const { return "MyObject1"; } };
struct MyObject2 { std::string GetSomeText() const { return "MyObject2"; } };
void UseTypeErasure() {
typedef std::vector<Object> ObjVect;
typedef ObjVect::const_iterator ObjVectIter;
ObjVect objVect;
objVect.push_back( Object( MyObject1() ) );
objVect.push_back( Object( MyObject2() ) );
for( ObjVectIter iter = objVect.begin(); iter != objVect.end(); ++iter )
std::cout << iter->GetSomeText();
}
就我而言,这似乎达到几乎是使用多态相同,或者也许不是(?)。
struct ObjectInterface {
virtual ~ObjectInterface() {}
virtual std::string GetSomeText() const = 0;
};
struct MyObject3 : public ObjectInterface {
std::string GetSomeText() const { return "MyObject3"; } };
struct MyObject4 : public ObjectInterface {
std::string GetSomeText() const { return "MyObject4"; } };
void UsePolymorphism() {
typedef std::vector<ObjectInterface*> ObjVect;
typedef ObjVect::const_iterator ObjVectIter;
ObjVect objVect;
objVect.push_back( new MyObject3 );
objVect.push_back( new MyObject4 );
for( ObjVectIter iter = objVect.begin(); iter != objVect.end(); ++iter )
std::cout << (*iter)->GetSomeText();
for( ObjVectIter iter = objVect.begin(); iter != objVect.end(); ++iter )
delete *iter;
}
最后一起为测试上述所有。
int main() {
UseTypeErasure();
UsePolymorphism();
return(0);
}