欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++ 模板类+重载 模仿Karto SLAM karto的基础类实现

程序员文章站 2024-03-25 09:35:28
...

Vector2<T>, Pose2,Pose3的相互引用以及Matrix3的实现
operator<< operator>>

#include <iostream>
#include <vector>
#include <cstring>
// #include <Eigen/Eigen>  
// using namespace Eigen;

using namespace std;

#include <cstddef>

/**
 * Karto type definition
 * Ensures platform independent types for windows, linux and mac
 */
#if defined(_MSC_VER)

  typedef signed __int8 kt_int8s;
  typedef unsigned __int8 kt_int8u;

  typedef signed __int16 kt_int16s;
  typedef unsigned __int16 kt_int16u;

  typedef signed __int32 kt_int32s;
  typedef unsigned __int32 kt_int32u;

  typedef signed __int64 kt_int64s;
  typedef unsigned __int64 kt_int64u;

#else

  #include <stdint.h>

  typedef int8_t kt_int8s;
  typedef uint8_t kt_int8u;

  typedef int16_t kt_int16s;
  typedef uint16_t kt_int16u;

  typedef int32_t kt_int32s;
  typedef uint32_t kt_int32u;

#if defined(__LP64__)
  typedef signed long kt_int64s;
  typedef unsigned long kt_int64u;
#else
  typedef signed long long kt_int64s;
  typedef unsigned long long kt_int64u;
#endif

#endif

typedef bool kt_bool;
typedef char kt_char;
typedef float kt_float;
typedef double kt_double;

template<typename T>
class Vector2
{
public:
    Vector2()
    {
        m_Values[0] = 0;
        m_Values[1] = 0;
    }

    Vector2(T x, T y)
    {
        m_Values[0] = x, m_Values[1] = y;
    }

public:
    inline const T& GetX() const
    {
        return m_Values[0];
    }
    inline const T& GetY() const
    {
        return m_Values[1];
    }

    inline void SetX(const T& x)
    {
        m_Values[0] = x;
    }

    inline void SetY(const T& y)
    {
        m_Values[1] = y;
    }

    inline void MakeFloor(const Vector2& rOther)
    {
        if (rOther.m_Values[0] < m_Values[0]) m_Values[0] = rOther.m_Values[0];
        if (rOther.m_Values[1] < m_Values[1]) m_Values[1] = rOther.m_Values[1];
    }
    inline void MakeCeil(const Vector2& rOther)
    {
        if (rOther.m_Values[0] > m_Values[0]) m_Values[0] = rOther.m_Values[0];
        if (rOther.m_Values[1] > m_Values[1]) m_Values[1] = rOther.m_Values[1];
    }

public:
    inline void operator += (const Vector2& rOther)
    {
        m_Values[0] += rOther.m_Values[0];
        m_Values[1] += rOther.m_Values[1];
    }

    friend inline std::ostream& operator << (std::ostream& rStream, const Vector2& rVector)
    {
        rStream << rVector.GetX() << " " << rVector.GetY();
        return rStream;
    }

    //friend不是成员函数。为什么不让这个重载写成成员函数?因为不希望调用函数的时候生成对象。 为什么不直接写在外面?因为这个操作需要操作类的private成员
    //operator 的二元运算符  如 +,-,==, >> , <<他们都是左边一个对象,右边一个对象。因此当函数是成员函数时,左操作对象默认为this,只需要加一个右操作对象,因此不能给 <<  >>这种成员函数写两个参数,但如果是friend,因为不是成员函数,所以要指定左右操作对象。
    friend inline std::istream& operator >> (std::istream& rStream, Vector2& rVector)
    {
        rStream >> rVector.m_Values[0] >> rVector.m_Values[1];
        if(!rStream) rVector=Vector2();
        return rStream;
    }
    
    //*********************************************下面的重载虽然成功了,但是没有实现像eigen那样   Matrix3d m;  m<<1,2,3,4;  这样的功能
    //*********************************************
    //此operator<< 为版本1,类内重载
    void operator<< (const T& a)
    {
        cout << "inside" << endl;
        this->m_Values[0]=a;
        this->m_Values[1]=a;
    }
    //*********************************************下面的重载虽然成功了,但是没有实现像eigen那样   Matrix3d m;  m<<1,2,3,4;  这样的功能
    //*********************************************
    //此operator<< 为版本2,友元重载,  版本1 和版本2一样,使用时候会发生 ambiguous overload错误,需要注释掉一个
    // friend void operator<<(Vector2& v1, const T& a)
    // {
    //     cout << "outside" << endl;
    //     v1.m_Values[0] = a;
    //     v1.m_Values[1] = a;
    // }
    

private:
    T m_Values[2];
};

class Pose3;  //Pose2中使用了Pose3,但是Pose3还没有声明
class Pose2
{
public:
    Pose2():m_Heading(0.0){}
    Pose2(const Vector2<double>& rPosition, double heading)
      : m_Position(rPosition)
      , m_Heading(heading)
    {
    }
    Pose2(kt_double x, kt_double y, kt_double heading)
      : m_Position(x, y)
      , m_Heading(heading)
    {
    }

    // Pose2(const Pose3& rPose);
    Pose2(const Pose3& rPose)
        : m_Position(1,2)
    {
        kt_double t1, t2;

        // calculates heading from orientation
    }    
    Pose2(const Pose2& rOther)
      : m_Position(rOther.m_Position)
      , m_Heading(rOther.m_Heading)
    {
    }    
public:
    inline kt_double GetX() const
    {
      return m_Position.GetX();
    }

    /**
     * Sets the x-coordinate
     * @param x the x-coordinate of the pose
     */
    inline void SetX(kt_double x)
    {
      m_Position.SetX(x);
    }

    /**
     * Returns the y-coordinate
     * @return the y-coordinate of the pose
     */
    inline kt_double GetY() const
    {
      return m_Position.GetY();
    }

    /**
     * Sets the y-coordinate
     * @param y the y-coordinate of the pose
     */
    inline void SetY(kt_double y)
    {
      m_Position.SetY(y);
    }

    /**
     * Returns the position
     * @return the position of the pose
     */
    inline const Vector2<kt_double>& GetPosition() const
    {
      return m_Position;
    }

    /**
     * Sets the position
     * @param rPosition of the pose
     */
    inline void SetPosition(const Vector2<kt_double>& rPosition)
    {
      m_Position = rPosition;
    }

    /**
     * Returns the heading of the pose (in radians)
     * @return the heading of the pose
     */
    inline kt_double GetHeading() const
    {
      return m_Heading;
    }

    /**
     * Sets the heading
     * @param heading of the pose
     */
    inline void SetHeading(kt_double heading)
    {
      m_Heading = heading;
    }

public:
    inline Pose2& operator = (const Pose2& rOther)
    {
        m_Position = rOther.m_Position;
        m_Heading = rOther.m_Heading;
        return *this;
    }        
    /**
     * Read pose from input stream
     * @param rStream input stream
     */
    friend inline std::istream& operator >> (std::istream& rStream, const Pose2& /*rPose*/)
    {
      // Implement me!!
      return rStream;
    }

    /**
     * Write this pose onto output stream
     * @param rStream output stream
     * @param rPose to read
     */
    friend inline std::ostream& operator << (std::ostream& rStream, const Pose2& rPose)
    {
      rStream << rPose.m_Position.GetX() << " " << rPose.m_Position.GetY() << " " << rPose.m_Heading;
      return rStream;
    }    

private:
    Vector2<double> m_Position;
    double m_Heading;
};

typedef std::vector< Pose2 > Pose2Vector;

class Pose3
{
public:
    /**
     * Default constructor
     */
    Pose3()
    {
    }
    Pose3(const Pose3& rOther)
    : m_Position(rOther.m_Position)
    , m_Orientation(rOther.m_Orientation)
    {
    }
private:
    Vector2<kt_double> m_Position;
    double m_Orientation;
};

class Matrix3
{
public:
    Matrix3()
    {
        Clear();
    }
    inline Matrix3(const Matrix3& rOther)
    {
        memcpy(m_Matrix, rOther.m_Matrix, 9*sizeof(double));
    }
    void Clear()
    {
      memset(m_Matrix, 0, 9*sizeof(kt_double));
    }
private:
    kt_double m_Matrix[3][3];
};


int main()
{
    Vector2<double> a(2,2);
    Vector2<double> b(3,3);
    b << 4;
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    return 0;
}