在没有显式模板特化的多态类中存储函数指针

时间:2014-05-22 06:28:05

标签: c++ templates polymorphism

我正在尝试创建一个辅助类来抽象调用函数指针。根据其他人对SO的反馈,我使用多态类来实现这一点(如下所示)。模板还用于减少代码重复。

typedef void(*PFNFOO1) (int);
typedef void(*PFNFOO2) (double);
typedef void(*PFNBAR1) (long);
typedef void(*PFNBAR2) (float);

typedef struct FOO_TABLE
{
    PFNFOO1 pfnFoo1;
    PFNFOO2 pfnFoo2;
} FOO_TABLE;

typedef struct BAR_TABLE
{
    PFNBAR1 pfnBar1;
    PFNBAR2 pfnBar2;
} BAR_TABLE;

enum TABLE_TYPE
{
    TYPE_FOO = 0,
    TYPE_BAR = 1,
};

template <typename T>
class FooBarImpl : public FooBarBase
{
public:  
    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
    void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
    void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
    void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }

    T* m_FooBarTable;
};

class FooBarBase
{
public:
    static FooBarBase* CreateFooBar(TABLE_TYPE tableType)
    {
        switch(tableType)
        {               
            case (TYPE_FOO) :
            {
                return new FooBarImpl<FOO_TABLE>();
            }
            break;

            case (TYPE_BAR) :
            {
                return new FooBarImpl<BAR_TABLE>();
            }
            break;
        }                

    }

    virtual void* GetpfnFoo1() = 0;
    virtual void* GetpfnFoo2() = 0;
    virtual void* GetpfnBar1() = 0;
    virtual void* GetpfnBar2() = 0;
};

int _tmain(int argc, _TCHAR* argv[])
{
    {
        FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
        // Initialize Foo table
        auto p = reinterpret_cast<PFNFOO1>(pFooBar->GetpfnFoo1());
        int parameter = 1;
        p(parameter);
    }

    {
        FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
        // Initialize Bar table
        auto p = reinterpret_cast<PFNBAR2>(pFooBar->GetpfnBar2());
        float parameter = 1.0f;
        p(parameter);
    }   

    return 0;
}

目前这给我带来了并发症错误,因为&#34; C2039:&#39; pfnBar1&#39; :不是&#39; FOO_TABLE&#39;&#34;这是有道理的,因为其中一个隐式模板专门化将尝试做&#34; offsetof(FOO_TABLE,pfnBar1),&#34;这是不允许的。我有两个问题。首先,我想知道解决此错误的最佳方法是什么。我想我可以通过为FooBarImpl和FooBarImpl提供明确的模板特化来解决这个问题,但是我想避免这样做,因为这意味着如果我稍后要添加一个新的表类型,我必须添加另一个专业化。此外,它增加了代码重复。因此,如果没有明确的模板专业化解决方法,请告知我们。

对于我的第二个问题,如果无法避免显式模板专业化,我也尝试了这个:

class FooBarBase;

template <typename T>
class FooBarImpl : public FooBarBase
{
};

template <>
class FooBarImpl<FOO_TABLE> : public FooBarBase
{
public:
    typedef FOO_TABLE T;

    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
    void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }

    T* m_FooBarTable;
};

template<>
class FooBarImpl<BAR_TABLE> : public FooBarBase
{
public:
    typedef BAR_TABLE T;

    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
    void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }

    T* m_FooBarTable;
};

但出于某种原因,我不断收到此错误&#34;错误C2504:&#39; FooBarBase&#39; :基类undefined&#34;即使它在我专门化模板之前工作正常。

如果有人对这两个问题有任何想法,我非常感谢您的反馈意见。感谢。

0 个答案:

没有答案