在学习KDL源码的时候,发现在“frames.hpp”中使用了大量的内联函数,涉及这些基础的类,向量(vector),旋转(rotation),坐标系(frame),力旋量(wrench),速度旋量(twist)等等。这也说明基础的类的包含的成员函数并不是十分复杂,符合内联函数的特点(规模较小、流程直接、频繁调用)。使用内联函数机制可以减小调用函数的开销。

KDL中的部分类定义(frames.hpp):

class Vector;
class Rotation;
class Frame;
class Wrench;
class Twist;
class Vector2;
class Rotation2;
class Frame2;

Vector部分的成员函数如下(frames.hpp):

class Vector
{
public:
    double data[3];
     //! Does not initialise the Vector to zero. use Vector::Zero() or SetToZero for that
     inline Vector() {data[0]=data[1]=data[2] = 0.0;}
 
     //! Constructs a vector out of the three values x, y and z
     inline Vector(double x,double y, double z);
 
     //! Assignment operator. The normal copy by value semantics.
     inline Vector(const Vector& arg);
 
     //! Assignment operator. The normal copy by value semantics.
     inline Vector& operator = ( const Vector& arg);
 
     //! Access to elements, range checked when NDEBUG is not set, from 0..2
     inline double operator()(int index) const;
 
     //! Access to elements, range checked when NDEBUG is not set, from 0..2
     inline double& operator() (int index);

具体的定义在“fames.inl”文件中:

IMETHOD Vector::Vector(const Vector & arg)
{
    data[0] = arg.data[0];
    data[1] = arg.data[1];
    data[2] = arg.data[2];
}
 
IMETHOD Vector::Vector(double x,double y, double z)
{
        data[0]=x;data[1]=y;data[2]=z;
}
 
 
IMETHOD Vector& Vector::operator =(const Vector & arg)
{
    data[0] = arg.data[0];
    data[1] = arg.data[1];
    data[2] = arg.data[2];
    return *this;
}

 在内联函数较多的情况下,为了避免头文件过长、版面混乱,可以将所有的内联函数定义移到一个单独的文件中去,然后再 用#include指令将它包含到类声明的后面(类的头文件的底部)。这样的文件称为一个内联函数定义文件。按照惯例, 应该将这个文件命名为“filename.inl”,其中“filename”与相应的头文件和实现文件相同。所以在frames.cpp末尾有#include "frames.inl"语句。