‘PitchMatrix3D’不是‘Matrix3D’的成员——linux下编译碰撞检测包ColDet

      ColDet是一个非常著名的开源碰撞检测包。我下载之后,使用包中自带的makefile.g++编译它,出现了一些bug:

g++ -c -O2 -DGCC coldet.cpp
In file included from box.h:28:0,
                 from coldetimpl.h:28,
                 from coldet.cpp:25:
math3d.h: 在成员函数‘void Matrix3D::rotate(const Vector3D&)’中:
math3d.h:232:44: 错误: ‘PitchMatrix3D’在此作用域中尚未声明
math3d.h:233:44: 错误: ‘YawMatrix3D’在此作用域中尚未声明
math3d.h:234:44: 错误: ‘RollMatrix3D’在此作用域中尚未声明
In file included from coldetimpl.h:28:0,
                 from coldet.cpp:25:
box.h: 在构造函数‘BoxTreeInnerNode::BoxTreeInnerNode(const Vector3D&, const Vector3D&, int)’中:
box.h:150:38: 错误: ‘NULL’在此作用域中尚未声明
box.h: 在成员函数‘virtual int BoxTreeInnerNode::getSonsNumber()’中:
box.h:165:18: 错误: ‘NULL’在此作用域中尚未声明
box.h:166:19: 错误: ‘NULL’在此作用域中尚未声明
box.h: 在成员函数‘virtual BoxTreeNode* BoxTreeInnerNode::getSon(int)’中:
box.h:177:12: 错误: ‘NULL’在此作用域中尚未声明
box.h: 在成员函数‘virtual BoxTreeNode* BoxedTriangle::getSon(int)’中:
box.h:193:43: 错误: ‘NULL’在此作用域中尚未声明
box.h: 在成员函数‘virtual BoxedTriangle* BoxedTriangle::getTriangle(int)’中:
box.h:198:12: 错误: ‘NULL’在此作用域中尚未声明
coldet.cpp: 在成员函数‘virtual bool CollisionModel3DImpl::collision(CollisionModel3D*, int, int, float*)’中:
coldet.cpp:51:33: 错误: ‘NULL’在此作用域中尚未声明
coldet.cpp: 在成员函数‘virtual bool CollisionModel3DImpl::getCollidingTriangles(float*, float*, bool)’中:
coldet.cpp:310:13: 错误: ‘NULL’在此作用域中尚未声明
coldet.cpp:316:13: 错误: ‘NULL’在此作用域中尚未声明
coldet.cpp:325:13: 错误: ‘NULL’在此作用域中尚未声明
coldet.cpp:331:13: 错误: ‘NULL’在此作用域中尚未声明
make: *** [coldet.o] 错误 1

      这个包 历史比较悠久了,包中自带的readme.txt中给出的说明是用g++ 2.8编译。我的gcc版本已经是4.6.3了。奇怪,为什么2.8编译通过的代码,4.6.3 竟然报错呢?

      根据错误提示,找到math3d.h中出现PitchMatrix3D的地方,一共有四处按照从上到下的顺序,第一处出现在struct Matrix3D中:

 friend Matrix3D PitchMatrix3D(const float theta);

第二处出现在struct Matrix3D的成员函数的定义中注意,这里就是第232行,出现关于PitchMatrix3D的错误)

inline void
Matrix3D::rotate(const Vector3D& v)
{
   if (v.x!=0.0f) *this = PitchMatrix3D(v.x) * (*this);
   if (v.y!=0.0f) *this = YawMatrix3D  (v.y) * (*this);
   if (v.z!=0.0f) *this = RollMatrix3D (v.z) * (*this);
}

第三处 第四处就是真正的PitchMatrix3D函数定义了:

inline Matrix3D
PitchMatrix3D(const float c, const float s)
{
   return Matrix3D(1.0f, 0.0f, 0.0f, 0.0f,
                   0.0f,    c,   -s, 0.0f,
                   0.0f,    s,    c, 0.0f,
                   0.0f, 0.0f, 0.0f, 1.0f);
}


inline Matrix3D
PitchMatrix3D(const float theta)
{
   return PitchMatrix3D((float) cos(theta), (float) sin(theta));
}

      PitchMatrix3D在此作用域中尚未声明 的错误让我纠结了很久。很显然,第三处和第四处就是PitchMatrix3D函数定义而已,没有错误。错就错在第二处。众目睽睽之下,struct Matrix3D的定义中明明写清楚了PitchMatrix3D是其友元函数,怎么到了第232行使用它的时候反而翻脸不认人了呢?难道结构体内 声明友元函数,结构体外不能直接使用吗?

      说到结构体,很多习惯了c++中class的人们可能感觉别扭。好吧,其实在c++中,结构体和类的唯一区别就是,在默认情况下,类数据成员和成员函数的访问控制是private,结构体数据成员和成员函数的访问控制是public。这里为了方便,不妨就认为PitchMatrix3DclassMatrix3D的友元函数。在网上某些帖子的提示下,我找到圣经《C++编程语言》的11.5.1节:友元的查找。里面有句话,我摘抄如下:

像成员函数一样,一个友元声明不会给外围的作用域引进一个名字。......对于大型程序和大的类,一个类不能‘默不作声地’给它的外围作用域加入一些名字,维持这种性质是非常好的事情。

     茅塞顿开有木有啊亲!《C++编程语言》牛逼至尊啊亲!

     我以迅雷不及掩耳盗铃儿响叮当仁不让之势,在PitchMatrix3D作为友元函数出现之前,加上了PitchMatrix3D函数的声明。同样地,加上YawMatrix3D和RollMatrix3D的函数声明。再make,这个让人蛋疼的编译错误就灰飞烟灭了。

     当然,还有其他错误,就是提示一大堆“‘NULL’在此作用域中尚未声明”这个小意思,NULL不是关键字,需要提前定义的。在出错的文件前面加上#include <cstddef>即可。

      编译成功之后,得到的最终结果就是一个名为libcoldet.a的库文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值