如果我创建一个模板类,那么我发送给该类的引用(指针)的其他类必须是模板化的?

时间:2017-02-15 11:56:14

标签: c++ templates

假设我this code有一个EnvelopeMultiPoints类template

#include <iostream>
#include <vector>

class EnvelopeMultiPointsBase
{
    // base
};

template<class T>
class EnvelopeMultiPoints : public EnvelopeMultiPointsBase
{
public:
    static unsigned int mNumPoints;

    EnvelopeMultiPoints() { }
    ~EnvelopeMultiPoints() { }

    void Process() {
        std::cout << "process: " << mNumPoints << std::endl;
    }
};

class Pitch : public EnvelopeMultiPoints<Pitch> { };

template<typename T>
unsigned int EnvelopeMultiPoints<T>::mNumPoints = 5;

class Container
{
public:
    EnvelopeMultiPointsBase *pAssociatedEnvelope;

    Container(EnvelopeMultiPointsBase *associatedEnvelope) : pAssociatedEnvelope(associatedEnvelope) { }
    ~Container() { }

    void Process();

private:
};

int main()
{
    EnvelopeMultiPoints<Pitch> pitch;
    Container container(&pitch);
    container.pAssociatedEnvelope->Process();
}   

我想传递给Container任何类型的“EnvelopeMultiPoints”类型(通用的“指针”),所以稍后我可以访问它自己的方法(在我的例子中,Process()

这是否意味着Container必须templated? (这在我的真实场景中是巨大的;很多工作在模板中转换它的所有方法,翻译header / cpp等等)。

还是有一个我不知道的伎俩?

简而言之:假设我想传递给Container EnvelopeMultiPoints<Pitch>,而不是执行Process()。之后,我想要传递EnvelopeMultiPoints<Volume>,而不是执行Process()。等等。有没有办法在不将Container转换为模板的情况下执行此操作?

2 个答案:

答案 0 :(得分:3)

您需要的技术称为dynamic polymorphism 这是由virtual functions在C ++中实现的。

说明使用您的代码:

class EnvelopeMultiPointsBase
{
public:

    // Abstract base, no actual implementation
    virtual void Process() = 0;
};

template<class T>
class EnvelopeMultiPoints : public EnvelopeMultiPointsBase
{
public:
    static unsigned int mNumPoints;

    EnvelopeMultiPoints() { }
    ~EnvelopeMultiPoints() { }

    // Some specific implementation.
    virtual void Process() override
    {
        std::cout << "process: " << mNumPoints << std::endl;
    }
};

class Pitch : public EnvelopeMultiPoints<Pitch>
{
};

答案 1 :(得分:2)

要调用基类的Process函数,必须在基类中定义它。您可以将实现移动到模板化子类:

class EnvelopeMultiPointsBase
{
    private:
    virtual void ProcessImpl() = 0;

    public:
    void Process() {
        //potential common code...
        ProcessImpl();
        //more potential common code...
    }
};

template<class T>
class EnvelopeMultiPoints : public EnvelopeMultiPointsBase
{
public:
    static unsigned int mNumPoints;

    EnvelopeMultiPoints() { }
    ~EnvelopeMultiPoints() { }

    private:
    void ProcessImpl() {
        std::cout << "process" << std::endl;
    }
};