C++ 在无显式模板专门化的多态类中存储函数指针
我试图创建一个助手类来抽象调用函数指针。根据其他人的反馈,我使用一个多态类来实现这一点(如下所示)。模板还用于减少代码重复C++ 在无显式模板专门化的多态类中存储函数指针,c++,templates,polymorphism,C++,Templates,Polymorphism,我试图创建一个助手类来抽象调用函数指针。根据其他人的反馈,我使用一个多态类来实现这一点(如下所示)。模板还用于减少代码重复 typedef void(*PFNFOO1) (int); typedef void(*PFNFOO2) (double); typedef void(*PFNBAR1) (long); typedef void(*PFNBAR2) (float); typedef struct FOO_TABLE { PFNFOO1 pfnFoo1; PFNFOO2 p
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;
}
typedef void(*PFNFOO1)(int);
类型定义无效(*PFNFOO2)(双);
类型定义无效(*PFNBAR1)(长);
类型定义无效(*PFNBAR2)(浮动);
typedef struct FOO_表
{
PFNFOO1-PFNFOO1;
PFNFOO2-PFNFOO2;
}富奥表;
typedef结构条形图表格
{
PFNBAR1 PFNBAR1;
PFNBAR2 PFNBAR2;
}吧台;
枚举表类型
{
类型_FOO=0,
类型_BAR=1,
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(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_foobatable;
};
食品类
{
公众:
静态foobase*CreateFooBar(表类型tableType)
{
开关(台式)
{
案例(类型_-FOO):
{
返回新的FooBarImpl();
}
打破
箱子(U型钢):
{
返回新的FooBarImpl();
}
打破
}
}
虚拟void*GetpfnFoo1()=0;
虚拟void*GetpfnFoo2()=0;
虚空*GetpfnBar1()=0;
虚空*GetpfnBar2()=0;
};
int _tmain(int argc,_TCHAR*argv[]
{
{
FooBarBase*pFooBar=FooBarBase::CreateFooBar(TYPE_FOO);
//初始化Foo表
自动p=重新解释(pFooBar->GetpfnFoo1());
int参数=1;
p(参数);
}
{
FooBarBase*pFooBar=FooBarBase::CreateFooBar(TYPE_FOO);
//初始化条表
自动p=重新解释(pFooBar->GetpfnBar2());
浮动参数=1.0f;
p(参数);
}
返回0;
}
这目前给我带来了复杂的错误“C2039:‘pfnBar1’:不是‘FOO_TABLE’的成员”,这是有意义的,因为其中一个隐式模板专门化将尝试执行“offsetof(FOO_TABLE,pfnBar1)”,这是不允许的。我有两个问题。首先,我想知道解决这个错误的最佳方法是什么。我想我可以通过为FooBarImpl和FooBarImpl提供显式的模板专门化来解决这个问题,但是我想避免这样做,因为这意味着如果我以后要添加一个新的表类型,我必须添加另一个专门化。此外,它还增加了代码重复。因此,如果有一种方法可以在没有显式模板专门化的情况下解决此问题,请让m知道
对于第二个问题,如果无法避免显式模板专门化,我也尝试了以下方法:
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;
};
class-foobase;
样板
FooBarImpl类:公共Foobaribase
{
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
类型def FOO_表T;
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(m_FooBarTable+funcOffset);
}
void*GetpfnFoo1(){return GetFunc(offsetof(T,pfnFoo1));}
void*GetpfnFoo2(){return GetFunc(offsetof(T,pfnFoo2));}
T*m_foobatable;
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
typedef BAR_表T;
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(m_FooBarTable+funcOffset);
}
void*GetpfnBar1(){return GetFunc(offsetof(T,pfnBar1));}
void*GetpfnBar2(){return GetFunc(offsetof(T,pfnBar2));}
T*m_foobatable;
};
但出于某种原因,我不断收到这个错误“error C2504:'FooBarBase':基类未定义”,即使在我专门化模板之前它工作正常
如果有人对这两个问题有想法,我将非常感谢您的反馈。谢谢。你到底想用这个实现什么?“助手类到抽象调用函数指针”-你没有抽象任何东西。。。您的客户端使用点假定特定的运行时类型和重新解释\u casts,以便可以恢复特定的成员。做
dynamic\u cast
所允许的事情实际上是一种不安全的尝试,但即使这样做也毫无意义,因为没有统一的基类行为来证明继承的合理性。为什么不创建一个包含FOO_TABLE和BAR_TABLE的并集以及一个int的结构来告诉您哪个是有意义的呢?你的额外代码除了模糊处理之外什么都买不到。这样做的主要目的是在创建函数表时,我们可以在调用函数指针时强制执行严格验证和松散验证。很难用一个小的自包含示例来说明这一点,所以请耐心听我说。此外,这些函数指针被多次调用,这样就省去了一堆重复的switch语句来确定应该从哪个表调用函数指针。而这不能用一个简单的wrapperfunction来完成吗?我这样问是因为我试图理解,在不破坏用例的情况下,代码的哪一部分是可以更改的。