C++具有纯虚函数的模板化返回值

C++ templated return value with pure virtual function

本文关键字:返回值 函数 C++      更新时间:2023-10-16

我有一个抽象的 Handle 类,其中包含对 T 类型的对象的引用。我希望能够将该类转换为 Handle,其中 U 是 T 的超类。我会使用继承,但这在这里不起作用。我将如何做到这一点?什么是好的选择?

伪代码示例:

template<class T>
class Handle {
public:
    virtual ~Handle () {}
    virtual T & operator* () const = 0;
    virtual T * operator-> () const = 0;
    virtual template<class U> operator Handle<U>* () const = 0; // being lazy with dumb pointer
};
template<class T>
class ConcreteHandle : public Handle<T> {
public:
    explicit template<class U> ConcreteHandle (U * obj) : obj(obj) {}
    virtual ~ConcreteHandle () {}
    virtual T & operator* () const {
        return *obj;
    }
    virtual T * operator-> () const {
        return obj;
    }
    virtual template<class U> operator Handle<U>* () {
        return new ConcreteHandle<U>(obj);
    }
private:
    T * obj;
};

根据要求,这就是我正在做的

class GcPool {
public:
    virtual void gc () = 0;
    virtual Handle<GcObject> * construct (GcClass clazz) = 0;
};
class CompactingPool : public GcPool {
public:
    virtual void gc () { ... }
    virtual Handle<GcObject> * construct (GcClass clazz) { ... }
private:
    Handle<GcList<Handle<GcObject> > > rootSet; // this will grow in the CompactingPool's own pool
    Handle<GcList<Handle<GcObject> > > knownHandles; // this will grow in the CompactingPool's own pool.
};

knownHandles需要与Handle兼容,因此它可以位于CompatingPool的rootSet中。rootSet也是如此。我将引导这些特殊手柄,这样就不会发生鸡和蛋的问题。

virtual template<class U> operator Handle<U>* () const  =0;

语言规范不允许使用模板虚函数。

在 ideone 处考虑以下代码,然后看到编译错误:

错误:模板可能不是"虚拟的"


现在你能做什么?一种解决方案是这样的:

template<class T>
class Handle {
public:
    typedef typename T::super super; //U = super, which is a superclass of T.
    virtual ~Handle () {}
    virtual T & operator* () const = 0;
    virtual T * operator-> () const = 0;
    //not a template now, but still virtual
    virtual super operator Handle<super> () const = 0;  
};

也就是说,在派生类中定义基类的typedef,并在Handle中使用它。像这样:

struct Base {//...};
struct Derived : Base { typedef Base super; //...};
Handle<Derived>  handle; 

或者,您可以将特征定义为:

struct Base {//... };
struct Derived : Base { //... };
template<typename T> struct super_traits;
struct super_traits<Derived>
{
   typedef Base super;
};
template<class T>
class Handle {
public:
    typedef typename super_traits<T>::super super; //note this now!
    virtual ~Handle () {}
    virtual T & operator* () const = 0;
    virtual T * operator-> () const = 0;
    //not a template now, but still virtual
    virtual super operator Handle<super> () const = 0; 
};

在我看来,super_traits是一个更好的解决方案,因为您可以在不编辑派生类的情况下定义派生类的特征。此外,您可以根据需要定义任意数量的类型定义;假设您的派生类有多个基,您可能希望定义许多 typedef,或者最好是类型列表。