作为减少复制/粘贴相同代码的繁琐工作的一种方式,我转向了黑暗面,并使用宏来代替我完成这项工作。
请注意,这段代码是从一个更大的生产代码中摘取出来的,在没有像这样的宏的帮助下,这个任务更加痛苦。具体来说,它是由一个字符串驱动的静态和虚拟函数的混合体。
现在我知道,宏可能会让你陷入麻烦,以这种方式使用它们相当“臭”,因此我想要更好的东西,但我很难想出比这更简单、更简洁的东西:
请注意,这段代码是从一个更大的生产代码中摘取出来的,在没有像这样的宏的帮助下,这个任务更加痛苦。具体来说,它是由一个字符串驱动的静态和虚拟函数的混合体。
现在我知道,宏可能会让你陷入麻烦,以这种方式使用它们相当“臭”,因此我想要更好的东西,但我很难想出比这更简单、更简洁的东西:
#define LAZY(name)\
static const char * identify() { return name; }\
virtual const char * getName() { return identify(); }
class A{
public:
LAZY("class A")
void foo(){
std::cout << getName() << std::endl;
}
};
class B: public A{
public:
LAZY("class B")
};
std::string somevar( B::identify() );
int main(void){
B b1;
B.foo();
}
我采用的其他方法(以及它们失败的原因)如下:
template<class T>
class Base{
public:
virtual const char * getName(){ return T::identify(); }
// All other functions driven by string. IE:
static void register(){ someFactory::reg( T::identify() ); }
virtual unsigned int getHash(){ return someHashFoo( T::identify() ); }
};
class A: public Base<A> {
public:
static const char * idenfity(){ return "class A"; }
void foo(){ std::cout << getname() << std::endl; }
};
class B: public A, public Base<B> {
// Conflict due to multi-inheritance.
};
另一种失败的方法是由于每个实例浪费内存,而且有点复杂:
class FaceBase{
public:
virtual const char * getName() =0;
};
template<class T>
class ImplBase: public FaceBase {
public:
virtual const char * getName(){ return T::identify(); }
};
class A{
public:
FaceBase & common;
static const char * identify(){ return "class A"; }
A(): common(ImplBase<A>()){}
virtual void foo(){ std::cout << common.getName() << std::endl; }
};
class B: public A{
static const char * identify(){ return "class B"; }
B(){ common = ImplBase<B>(); }
};
typeid
有什么问题吗? - slaphappytype_info::name
might返回一个混淆的名称,但这只是一个实现细节,因为有趣的部分是operator==
。 - slaphappy