模板多态性

Template polymorphism

本文关键字:多态性      更新时间:2023-10-16

我最近收到了一个非常好的答案,即如何通过派生类来重载特定的类成员。

现在的问题是,其中一个成员实际上是模板化的,专业化要么是BaseClass,要么是DerivedClass,要么是Derived2Class

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

template<class T>
class Queue
{
    public:
        Queue();
        Queue(T*);
}
class Com
{
    public:
        virtual void setReady()
        {
            cout << "Com" << endl;
        }
};
class DerivedCom : public Com
{
    public:
        void setReady()
        {
            cout << "DCom" << endl;
        }
};
class Derived2Com : public Com
{
    public:
        void setReady()
        {
            cout << "D2Com" << endl;
        }
};
class BaseClass
{
    protected:
        Com* com;
        Queue<BaseClass>* queue;
    public:
        BaseClass(Com* c = new Com, Queue<BaseClass>* q = new Queue<BaseClass>) : com(c), queue(q)
        {
        }
        void setReady()
        {
            com->setReady();
        }
};
class DerivedClass : public BaseClass
{
    public:
        DerivedClass() : BaseClass(new DerivedCom, new Queue<DerivedClass>) 
        {
        }
};
class Derived2Class : public BaseClass
{
    public:
        Derived2Class() : BaseClass(new Derived2Com, new Queue<Derived2Class>) 
        {}
};
int main()
{
    BaseClass* base = new Derived2Class();
    base->setReady();
    return 0;
}

我可以毫无问题地"重载"简单的类,如ComDerivedComDerived2Com,但BaseClass的构造函数签名不适合派生类试图发送的类型。

而不是

Queue<BaseClass>* queue;你应该Queue<BaseClass*> queue;,或者更好的是,Queue<std::unique_ptr<BaseClass>>并仅在基构造函数中初始化它:

BaseClass(Com* c = new Com, Queue<BaseClass*> q = Queue<BaseClass*>()) : com(c), queue(q)
{
}

但是,让BaseClass将自己的集合作为成员保存是一种代码气味。我会重新考虑那部分。

它不起作用的原因是Queue<BaseClass>Queue<DerivedClass>完全不同的类

你实际上应该有Queue<BaseClass*>* queue = new Queue<BaseClass*>(); 这在堆上声明了一个 BaseClass 指针类型的队列指针,并允许您使用上面提到的指针表示法作为queue->push(&BaseClass::setReady);等等......

根据在其他地方找到的答案,我将类Queue的概念更改为无模板。