用C++03的方法简化接口声明

Simplifying an interface declaration the C++03 way

本文关键字:接口 声明 方法 C++03      更新时间:2023-10-16

为了减少复制/粘贴同一代码的繁忙工作,我转向了黑暗面,并使用了一个宏来为我做这件事。

请记住,如果没有像这样的宏来帮助,它的生产代码要大得多,任务也要痛苦得多。具体来说,它是由单个字符串驱动的静态和虚拟函数的混合体。

现在我知道宏会给你带来麻烦,这样使用它们非常"糟糕",所以我想要更好的东西,但我很难想出像这样简单简洁的东西:

#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>(); }
};

您实际上没有问任何问题,但假设是"没有宏,我怎么能以干净的方式做到这一点?",并进一步假设您所指的"更大"的任务是一个完全自定义的RTTI系统,答案是"你不能。"

据我所知,每一个做这种事情的大项目(MFC、Qt、LLVM)都会做其中一个:

  • 使用宏。(MFC和某种程度上的Qt)
  • 使用自定义代码生成器。(Qt和在某种程度上LLVM)
  • 编写样板代码。(LLVM)