c/c++ 奇技淫巧(一些c语言的技巧)

2020-01-06 16:59:17刘景俊

如果说我们的基类有10个函数,我们从这个基类派生了20个类,那么我们就需要额外做200个函数声明。但是这些声明的目的往往只是为了Implement基类中的那些方法而已,这就或多或少的容易使得头文件不好维护。
传统方法的实现
如果说我们有一个Animal的类,这个类被视为基类,我们希望从这个基类派生出不同的子类。在Animal中有3个纯需函数,如下所示:


class Animal 
{ 
public: 
virtual std :: string GetName () const = 0 ; 
virtual Vector3f GetPosition () const = 0; 
virtual Vector3f GetVelocity () const = 0; 
}; 

同时,这个基类拥有三个派生类——Monkey,Tiger,Lion。
那么我们三个方法的每一个都会在7个地方存在:Animal中一次,Monkey、Lion、Tiget的声明和定义各一次。
然后假设我们做一个小改动——我们想将GetPosition和GetVelocity的返回类型改为Vector4f以适应Transform变换,那么我们就要在7个地方进行修改:Animal的.h文件,Lion、Tiger和Monkey的.h文件和.cpp文件。
使用宏的实现
有一种很妙的处理方法就是将这些方法进行包装,改成所谓接口宏的形式。我们可以试试看:


#define INTERFACE_ANIMAL(terminal)             
public:                           
  virtual std::string GetName() const ##terminal     
  virtual IntVector GetPosition() const ##terminal    
  virtual IntVector GetVelocity() const ##terminal    

#define BASE_ANIMAL   INTERFACE_ANIMAL(=0;)
#define DERIVED_ANIMAL INTERFACE_ANIMAL(;)

值得一提的是,##符号代表的是连接,符号代表的是把下一行的连起来。
通过这些宏,我们就可以大大简化Animal的声明,还有所有从它派生的类的声明了:


// Animal.h
class Animal
{
  BASE_ANIMAL ;
};



// Monkey.h
class Monkey : public Animal
{
  DERIVED_ANIMAL ;
};


// Lion.h
class Lion : public Animal
{
  DERIVED_ANIMAL ;
};


// Tiger.h
class Tiger : public Animal
{
  DERIVED_ANIMAL ;
};

 

 
注:相关教程知识阅读请移步到C++教程频道。