C ++抽象模板类型,保持T(虚拟)

时间:2016-08-15 21:06:43

标签: c++ templates c++11 polymorphism virtual

我编写了一组两个类来帮助实现多态,更具体地说,在我们有一个指向基类的指针集合的情况下,我们存储派生类。

有两种实现方式,一种是当前使用,另一种是实验版本。当前实现在运行时工作,每个类有一个Type的静态实例,它跟踪它的父和子Type(s); Object类用作所有其他类的基类(包括用于为Type检索创建必要的静态和虚拟方法的宏。

实验性实施(此处相关的实施)包含模板化的Type<T>和适用于新Object的{​​{1}}相同的结构。新Type<T>使用Type<T>进行所有操作。

接下来是实验课的来源:

<type_traits>

Type.h

一切正常,没有问题,当我们开始进入#ifndef QUIDOR_EXPERIMENTAL_TYPE_H #define QUIDOR_EXPERIMENTAL_TYPE_H // std #include <type_traits> namespace quidor { namespace experimental { template<class T> class Type { public: typedef T class_type; public: template<class O> // is<O> bool operator ==(const Type<O> &) const { return std::is_same<class_type, O>(); } // more operators like the previous one Type() = default; ~Type() = default; }; } } #endif //QUIDOR_EXPERIMENTAL_TYPE_H 及其衍生产品时,就会出现问题。

Object

Object.h

问题在于一个功能:

#ifndef QUIDOR_EXPERIMENTAL_OBJECT_H #define QUIDOR_EXPERIMENTAL_OBJECT_H // quidor #include "Type.h" #define QuidorObjectMeta(class) \ public: \ static constexpr const char * className() { \ return #class; \ } \ \ static const quidor::experimental::Type<class> classType() { \ return quidor::experimental::Type<class>(); \ } \ \ virtual const quidor::experimental::Type<class> getClassType() const { \ return class::classType(); \ } \ private: //\ObjectMeta(class) namespace quidor { namespace experimental { class Object { public: static const Type<Object> classType() { return Type<Object>(); } virtual const Type<Object> getClassType() const { return Object::classType(); } Object() = default; virtual ~Object() = default; private: }; } } #endif //QUIDOR_EXPERIMENTAL_OBJECT_H

派生类virtual const Type<Object> getClassType() const将此虚拟方法定义为(Derived之后):

ObjectMeta

现在这显然不合法,因为virtual const Type<Derived> getClassType() const的返回类型无法改变getClassType()中声明的内容。

需要存在虚拟方法,因为它表示我们如何从例如Object类型的变量中获取实例的实际类型,这是所需的功能:

Object *

我找到的唯一解决方案是为#include <quidor/experimental/Object.h> #include <cassert> class Derived : public quidor::experimental::Object { QuidorObjectMeta(::Derived, quidor::experimental::Object); Derived() = default; virtual ~Derived() = default; }; int main(int argc, char ** argv) { using quidor::experimental; Object * o = new Derived(); assert(o->getClassType() == Derived::classType()); // true delete o; return 0; } 创建一个非模板化的基类,然后返回该问题,当这个基类无法知道它的Type<T>时,会出现问题T;此基类也不能使用虚方法,因为此方法必须模板化以接收其他类型(Type<T>代码中的O),并且模板化虚拟方法不合法。

所以我来这里是为了解决这个问题,如果有,如果没有,为什么以及它是如何工作的。提前谢谢。

1 个答案:

答案 0 :(得分:1)

您似乎正在尝试构建与Smalltalk层次结构非常相似的东西,其中每个类都有一个元类(它本身就是一个对象 - 即一个类的实例)。

在Smalltalk中,这是用 1

这样的结构处理的

enter image description here

其中,实线表示继承,虚线表示实例(即,A - - > B表示A是B的实例)。灰色线在正常的类层次结构中,黑色线在元类层次结构 2 中。

其中一些可能很难在C ++中建模,特别是Metaclass和Metaclass类之间的关系,其中Metaclass的元类本身就是Metaclass的一个实例。

我不确定这是否足以准确地模拟系统;如果没有,你可能想花些时间阅读我在脚注1中引用的那本书。

  1. 虽然我已经重新绘制了它,但它本质上是来自 Smalltalk-80:语言及其实现的图16.5的副本。
  2. 我意识到这种符号有点不同寻常 - 但它是原来使用的,我试图合理准确地保存它。