模板类的继承问题

时间:2009-03-09 12:45:02

标签: c++ inheritance

有人能想出一个很好的方法让下面的代码工作吗? (再次,这是一种令人难以置信的简化方式)

template <class f, class g> class Ptr;

class RealBase { };

template <class a, class b, class c = Ptr<a,b> > class Base : public RealBase { public: Base(){}; };

template <class d, class e> class Derived : public Base <d,e> { public: Derived(){}; void DerivedMethod(){}; }; template <class f, class g> class Ptr { public: Ptr(){}; Ptr(Base<f,g,Ptr<f,g> >* a){in = a;}; Base<f,g,Ptr<f,g> >* operator->() { return in; }; private: Base<f,g,Ptr<f,g> >* in; };

typedef Derived<double,double> DDerived;

int main() { Base<int,int> b = Base<int,int>(); Derived<double,double> d = Derived<double,double>(); DDerived dd = DDerived(); Ptr<double,double> p(&dd); p->DerivedMethod(); return 1; }

目前编译器因为Base&lt;&gt;而呻吟没有DerivedMethod();

修改

我确实理解这里的问题,我在第一种情况下缺乏解释是不好的(我很匆忙)。 [顺便说一下,这是非常简化的代码,是的,为了简单起见,我没有实际做任何事情的析构函数或方法。只是忽略它,它对问题没有任何影响。]

我需要发生的是,只处理派生类(D_Derived)的迭代器(此处未详述)需要访问派生类中包含的方法而不是基类。简单地将此方法引入基类并不是一个真正的选择,因为如果我必须这样做,这个错误将会发生很多。 (在真正的基类上构建了大约10个类,它们都有自己的派生方法。就像其中的20个。每个。)

有人能想到另一种实现此功能的方法吗?

5 个答案:

答案 0 :(得分:2)

此代码不起作用,因为模板类Ptr返回基类模板的对象而不是派生模板类。派生方法是派生模板的一部分,因此会引发编译错误。如果DerivedMethod是基本模板的一部分,那么此代码将起作用

答案 1 :(得分:1)

这是有道理的。 Base没有这样的方法(DerivedMethod)。如果DerivedMethod是基类的虚函数(可能是pure),它就可以工作。

答案 2 :(得分:1)

编译器是对的。为了能够访问方法,必须以编译器看到的类型声明此方法(这称为变量的静态类型)。在您的情况下,此类型为Base<…>,并且编译器不知道它是其他类型。

答案 3 :(得分:1)

使用抽象类和成员名称很难弄清楚你真正想要实现的目标。如果您真的必须将Ptr中的指针视为D_Derived,请将访问者成员添加到Ptr并使用类型转换:

class Ptr {
    ...

    Base<f,g,Ptr<f,g> >* get() {
        return in;
    }
};

...

D_Derived* ptr = dynamic_cast<D_Derived*>(p.get());
if (ptr) {
    ptr->DerivedMethod();
}

编辑:正如Konrad Rudolph指出的那样,为了使用动态强制转换,您必须向基类添加一个虚方法。

实际上,为每个要用作基类的类定义虚拟析构函数是一个好习惯,以确保调用派生类的析构函数(More Information)。

class RealBase {
public:
    virtual ~RealBase() {}
};

答案 4 :(得分:0)

行。在尝试了大约10种不同的方法(static_castreinterpret_cast等)之后,您可以将它投射出来。

int main()
{
    Base&lt;int,int> b = Base&lt;int,int>();
    Derived&lt;double,double> d = Derived&lt;double,double>();
    DDerived dd = DDerived();
    Ptr&lt;double,double> p(&dd);
    DDerived * fauxpointer;
    fauxpointer = (DDerived\*) &(*p);
    fauxpointer->DerivedMethod();
    return 1;
}

讨厌。但它确实有效,而这一切都很重要。

向所有重复这个问题的人欢呼。