我的问题类似于:Can't use macro define class in C++ ,但有点复杂:
class ABC
{
public:
DECLARATION(ABC)
private:
void ABCFun1();
void ABCFun2();
// ... and so on
}
#define DECLARATION(TYPE)\
std::string GetClassName()\
{\
return std::string(#TYPE);
}\
// the macro can goes on to declare more
// common interfaces, like Initialize(), ...etc.
所以,重点是,我可以使用这个宏来生成其他类,例如 DEF
、GHI
...等等,
它们都共享 DECLARATION
的公共(public)部分,但也有自己的 private
零件。
如果不需要GetClassName()
,好像只能用宏#
来实现,
然后我可以使用继承将它们放在一起。
或者,如果没有私有(private)的东西,我可以使用模板。
那么,将这两个东西混在一起,有什么办法可以避免宏?
谢谢!
最佳答案
您可以联系我们 CTRP生成一些函数。但请记住,除非您使用宏,否则名称将不可用(当编译时反射成为标准时,这将会改变,可能对于 C++17)。
CRTP:
template<typename T>
class Base
{
public:
void myFunc()
{
((T*)this)->functionA();
((T*)this)->functionB();
// ...
}
};
class ABC : public Base<ABC>
{
// ...
};
编辑:BЈовић 的回答是正确的,但是关于 RTTI 的一些评论:
- 不可携带
-
typeid(T).name()
依赖于实现(如果实现者愿意,它可以为每种类型返回""
) - 它很慢。
参见 this question about RTTI and LLVM ,例如(或 this one about performance )。
要存储字符串,您应该像现在一样使用预处理器。请注意,它不适用于模板化参数(即,如果您有 template<typename T>
,则 #T
将扩展为 "T"
,而不是实际的类型名称)。
然后,有一种技术允许将字符串传递给模板参数(类似的):
#define NAME( _n_ , _t_ ) \
struct _t_ \
{ \
static const char* asName() \
{ \
return #_n_; \
} \
}
它将字符串更改为一种类型。字符串本身是一个乱码,因此它被直接放入可执行文件中(并且是只读的,尝试修改它很可能会导致崩溃)。
我在 SPARK 粒子引擎中使用它,例如,我在其中实现了一个反射模块。
关于c++ - 如何用继承或模板(或其他任何东西?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22063659/