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

标签 c++ templates virtual abstract-class

我有一个抽象的 Handle 类,它包含对 T 类型对象的引用。我希望能够将该类转换为 Handle,其中 U 是 T 的父类(super class)。我会使用继承,但这在这里不起作用。我该怎么做呢?什么是好的替代品?

示例伪代码:

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;

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

考虑 this code at ideone ,然后看到编译错误:

error: templates may not be ‘virtual’


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

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;假设你的派生类有多个基类,你可能想定义很多 typedef,或者最好是 typelist .

关于带有纯虚函数的C++模板返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6026234/

相关文章:

java - 如何在Android的Qt上使用HockeyApp SDK

c++ - 成员函数模板特化可以具有与主模板不同的访问级别吗?

c++ - 模板类的部分模板特化,如 std::function

c++ - 在基类 vector 上调用虚函数

c++ - g++ 忽略被覆盖的虚函数

c++ - 抽象类 C++

c++ - 为什么map.find使用<运算符而不是==运算符?

c++ - 我该怎么做——像一个人一样快速地修改 2 的幂++ 2 的幂?

c++ - 仅在监听套接字上使用选择?

go - 如何忽略Go模板/文本中的元素