查看: 1252|回复: 4

《设计与实践》一书关于仿函数的疑问

[复制链接]

该用户从未签到

发表于 2010-12-8 21:32:24 | 显示全部楼层 |阅读模式
5.2.5 信息获取和统计 中提到仿函数Class SimpleFunctor
{
public:
    void operator()(int &i)
    {
       .....
    }
};
和如下函数有同样的被调用的方式
SimpleFuncotr(int &i)
{
    ...
}

疑问1
由于成员函数有隐藏参数SimpleFunctor* this,成员函数和普通函数还是有区别的

疑问2
很长,先贴书中代码
  1. #include <osg\io_utils>
  2. #include <osg\TriangleFunctor>
  3. #include <osg\Drawable>
  4. #include <osgDB\ReadFile>
  5. #include <iostream>

  6. class AttributePrinter : public osg::Drawable::AttributeFunctor
  7. {
  8. public :
  9. typedef osg::Drawable::AttributeType AttributeType;
  10. inline const char * getTypeName(AttributeType type)
  11. {
  12. static const char* typeNames[]=
  13. {
  14. "Vertices","Weights","Normals","Colors","Secondary Colors",
  15. "Fog Coords","Attribute6","Attribute7",
  16. "Texture Coords 0","Texture Coords 1","Texture Coords 2",
  17. "Texture Coords 3","Texture Coords 4","Texture Coords 5",
  18. "Texture Coords 6","Texture Coords 7"
  19. };
  20. return typeNames[type];
  21. }

  22. template < typename T>
  23. void printInfo(AttributeType type, unsigned int size, T* front)
  24. {
  25. std::cout << "***" << getTypeName(type) <<":" << size <<std::endl;
  26. for (unsigned int i=0; i<size ;i++)
  27. {
  28. std::cout << "(" << *(front + 1) << ");" ;
  29. }
  30. std::cout <<std::endl<< std::endl;
  31. }

  32. virtual void apply(AttributeType type ,unsigned int size ,float* front)
  33. {
  34. printInfo(type,size,front);
  35. }


  36. virtual void apply(AttributeType type ,unsigned int size ,osg::Vec2* front)
  37. {
  38. printInfo(type,size,front);
  39. }

  40. virtual void apply(AttributeType type ,unsigned int size ,osg::Vec3* front)
  41. {
  42. printInfo(type,size,front);
  43. }

  44. virtual void apply(AttributeType type ,unsigned int size ,osg::Vec4* front)
  45. {
  46. printInfo(type,size,front);
  47. }


  48. };

  49. struct TrianglePrinter
  50. {
  51. TrianglePrinter()
  52. {
  53. std::cout<< "****Triangles***" << std::endl;
  54. }

  55. void operator()(const osg::Vec3 & v1,const osg::Vec3 & v2,
  56. const osg::Vec3 & v3,bool) const
  57. {
  58. std::cout << "(" << v1 << ");" << "(" << v2 << ");" << "(" << v3 << ")" << std::endl;
  59. }
  60. };

  61. class FindGeometryVisitor: public osg::NodeVisitor
  62. {
  63. public:
  64. FindGeometryVisitor()
  65. :osg::NodeVisitor(TRAVERSE_ALL_CHILDREN){}
  66. virtual void apply(osg::Node &node)
  67. {
  68. traverse(node);
  69. }

  70. virtual void apply(osg::Geode &node)
  71. {
  72. for (unsigned int i=0; i<node.getNumDrawables(); i++)
  73. {
  74. osg::Drawable* drawable = node.getDrawable(i);
  75. if (!drawable)
  76. {
  77. continue;
  78. }
  79. std::cout << "[" << drawable->libraryName()
  80. << "::" << drawable->className() << "]" <<std::endl;

  81. AttributePrinter attrPrinter;
  82. drawable->accept(attrPrinter);

  83. // 这里就是疑问产生处
  84. osg::TriangleFunctor<TrianglePrinter> triPrinter;
  85. drawable->accept(triPrinter);

  86. std::cout<< std::endl;
  87. }
  88. traverse(node);
  89. }
  90. };

  91. int main(int argc, char** argv)
  92. {
  93. osg::ArgumentParser arguments(&argc, argv);
  94. osg::Node * model = osgDB::readNodeFiles(arguments);
  95. if (!model)
  96. {
  97. model = osgDB::readNodeFile("exported.ive");
  98. }

  99. FindGeometryVisitor fgv;
  100. if (model)
  101. {
  102. model->accept(fgv);
  103. }

  104. getchar();

  105. return 0;
  106. }
复制代码



osg::TriangleFunctor<TrianglePrinter> triPrinter;
drawable->accept(triPrinter);

运行后,triPrinter确实被输出了,也就是重载()被顺利调用,
要达到这个效果我理解应该满足:
1,TriangleFunctor实现了apply()方法
2,在被实现的apply()方法中有一个和TrignlePrinter的操作符()同样参数格式的函数;

通过看源码,1的出处找到了。但是2没有找到。
疑问2:
被重载的()是何时被调用的?

该用户从未签到

发表于 2010-12-9 08:48:36 | 显示全部楼层
include/osg/TriangleFunctor,看一看drawElements的实现

至于drawElements函数的调用时机,看一看Geometry::accept的实现

该用户从未签到

 楼主| 发表于 2010-12-9 10:24:55 | 显示全部楼层
本帖最后由 CR苏杭 于 2010-12-9 10:30 编辑

呃,geometry::accept的省略下来就是
functor.begin()
  functor.vertex()
functor.end()

functor.end()中 调用了functor::drawarray;
而drawarray调用了operator()
我用的2.8.2。
===
看了2.9.6的trianglefunctor,它的end()里面也是调用了drawarray啊

该用户从未签到

发表于 2010-12-9 13:24:44 | 显示全部楼层
一样吧~~都要调用operator()啊

该用户从未签到

 楼主| 发表于 2010-12-9 13:37:30 | 显示全部楼层
嗷。嗷。。嗷。酱。还以为版本更新以后这里变化了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表