zl程序教程

您现在的位置是:首页 >  工具

当前栏目

开源库之LibQglViewer-源码剖析3/15 --Vector3.h

源码开源 -- 15 剖析
2023-09-27 14:21:08 时间

0. 该类仅仅属于库的内部类,不需要导出声明

1. 包含标准异常库,定义表量常量

#include <stdexcept>

#ifndef FLT_MAX
# define FLT_MAX 9.99E20f
#endif

2. 引入命名空间vrender

namespace vrender
{
}

 

3. 在vector3.h中的内容

3.1 引入NVector3类的前置声明,不需要具体定义,只需要在cpp文件中引入具体定义文件即可

3.2 定义了Vector3类的接口

3.3 定义了Vector3类的静态常量类变量,该变量在类的存储空间内(程序的全局堆栈空间内创建)

    class Vector3
    {
        public:
            // ---------------------------------------------------------------------------
            //! @name Constant
            //@{
            static const Vector3 inf;
            //@}

需要注意,初始化必须在CPP文件中直接给出初始化,在全局(命名空间)范围初始化。

const Vector3 Vector3::inf(FLT_MAX, FLT_MAX, FLT_MAX); 

 

 

 

 

3.4 构造函数提供了4种:

            Vector3 ();              //默认构造函数
            ~Vector3 ();              //析构函数
            Vector3 (const Vector3&);      //复制构造函数
            Vector3 (const NVector3&);      //其他类的转换构造函数
            Vector3 (double, double, double);  //一般构造函数

3.5 inline 定义内联函数,提高调用效率

            inline double  x() const { return _xyz[0]; }
            inline double  y() const { return _xyz[1]; }
            inline double  z() const { return _xyz[2]; }
            inline void  setX(double r) { _xyz[0] = r; }
            inline void  setY(double r) { _xyz[1] = r; }
            inline void  setZ(double r) { _xyz[2] = r; }
            inline void  setXYZ (double x,double y,double z) { _xyz[0] = x; _xyz[1] = y; _xyz[2] = z; }

同理,Vector3类型的逻辑运算,也是inline函数

            inline Vector3& operator+= (const Vector3& v)
            {
                _xyz[0] += v._xyz[0];
                _xyz[1] += v._xyz[1];
                _xyz[2] += v._xyz[2];
                return *this;
            }

            inline Vector3& operator-= (const Vector3& v)
            {
                _xyz[0] -= v._xyz[0];
                _xyz[1] -= v._xyz[1];
                _xyz[2] -= v._xyz[2];
                return *this;
            }

            inline Vector3& operator*= (double f) { _xyz[0] *= f; _xyz[1] *= f; _xyz[2] *= f; return *this;}
            inline Vector3& operator/= (double f) { _xyz[0] /= f; _xyz[1] /= f; _xyz[2] /= f; return *this;}

 

3.6 赋值函数声明(重载赋值=符号):operator=()

(1)其中一个可以直接在.h文件种实现,因此声明为inline内敛函数。另一个需要在.cpp种实现,则常规函数

(2)尽管类成员都为private,但是在其函数实习中,还是可以直接调用相应类型的成员直接访问。

(3)赋值重载函数返回值,用引用类型,并用return *this 返回,这样可以连续调用=, 即A1=A2=A3

      inline Vector3& operator= (const Vector3& u) { _xyz[0] = u._xyz[0]; _xyz[1] = u._xyz[1]; _xyz[2] = u._xyz[2]; return *this; }
          Vector3& operator= (const NVector3& u);

 

3.7 类的静态函数声明

(1)注意,std::min(), std::max() 函数在<algorithm>头文件中 ,因此需要添加在cpp的开头

(2)声明为静态函数,作为类的函数直接调用,作用是:获取空间两个点的极点坐标(空间包围盒创建)

            static Vector3 mini(const Vector3&,const Vector3&) ;
            static Vector3 maxi(const Vector3&,const Vector3&) ;

实现cpp

Vector3 Vector3::mini(const Vector3& v1,const Vector3& v2)
{
  return Vector3(std::min(v1[0],v2[0]),std::min(v1[1],v2[1]),std::min(v1[2],v2[2])) ;
}

Vector3 Vector3::maxi(const Vector3& v1,const Vector3& v2)
{
  return Vector3(std::max(v1[0],v2[0]),std::max(v1[1],v2[1]),std::max(v1[2],v2[2])) ;
}

3.7 声明为friend的友元函数,在类中定义,

            friend Vector3 operator- (const Vector3& u) { return Vector3(-u[0], -u[1], -u[2]); }

函数实现如下cpp文件进行实现,

 

则可在该函数内部访问该类的私有成员,如下

 

 

// -----------------------------------------------------------------------------
//! Out stream override: prints the 3 vector components
std::ostream& vrender::operator<< (std::ostream& out,const Vector3& u)
{
  out << u[0] << " " << u[1] << " " << u[2];
  return ( out );
}

 

 

 

 

3.8  限定符const修饰的类成员函数,则不能在函数体内修改类的成员


            inline Vector3 operator+(const Vector3& u) const
            {
                return Vector3(_xyz[0]+u._xyz[0],_xyz[1]+u._xyz[1],_xyz[2]+u._xyz[2]);
            }
            inline Vector3 operator-(const Vector3& u) const
            {
                return Vector3(_xyz[0]-u._xyz[0],_xyz[1]-u._xyz[1],_xyz[2]-u._xyz[2]);
            }

            inline double    operator*(const Vector3& u) const
            {
                return _xyz[0]*u._xyz[0] + _xyz[1]*u._xyz[1] + _xyz[2]*u._xyz[2];
            }

 

4. 在vector3.cpp文件中,则引入具体的实现的头文件,以及其他类的具体定义

#include <iostream>  //使用到的表顺输入输出库
#include "Vector3.h" 
#include "NVector3.h"  //引入具体定义文件
#include <math.h>    //使用到的数学库
#include <algorithm>  //使用到的算法库

4.1 直接引用明明空间,这样在cpp文件中,直接使用相关变量:

using namespace vrender;
using namespace std;

 

5. 文件包含关系