为什么80%的码农都做不了架构师?>>>   

Conversion Operators in OpenCascade

eryar@163.com

Abstract. C++ lets us redefine the meaning of the operators when applied to objects. It also lets us define conversion operations for class types. Class-type conversions are used like the built-in conversions to implicitly convert an object of one type to another type when needed. A conversion operator provides a way for you to define how an object can be converted automatically to a different type. The paper gives some conversion operators examples in OpenCascade.

Key words. OpenCascade, Conversion Operators, Operator overloading

1. Introduction

C++允许我们重新定义操作符用于类类型对象时的含义。如果需要,可以像内置转换那样使用类类型转换,将一个类型对象隐式转换到另一类型。如在OpenCascade中经常看到如下类似的代码:

TopoDS_Shape theSphere  =  BRepPrimAPI_MakeSphere( 1.0 );

其中,BRepPrimAPI_MakeSphere也是一个类,直接赋值给了另一个类TopoDS_Shape的对象theSphere。第一次这么来用的时候有些困惑,不知道你有没有这样的疑问,不管你有没有,反正我是有的(Just kidding)。后来才知道,这就是一种重载方式,重载了类型转换操作符(Conversion Operator)。

使用类型转换操作符在将一种类型转换到另一种类型时,感觉自然。当类较多且经常需要进行类型之间的转换时,定义类型转换操作符还是很方便的。本文结合OpenCascade程序来体验使用类型转换操作符带来的便利。

2. Conversion Operators

转换操作符(Conversion Operators)提供了从一种对象类型自动转换到另一种类型的方式。一个经典例子就是自定义字符串类,但是可以将这个自定义的字符串类当作函数参数传给const char*类型的函数,如标准C中的一些函数:strcmp(), strlen()。示例程序如下所示:

class MyString
{ public:MyString(const char* string); // convert MyString to a C-style string. operator const char*() { return mBuffer; } private: char* mBuffer; int mLength;
}; // MyString objects get automatically converted to const char* MyString mystr("Haggis"); int same = strcmp(mystr, "Edible"); int len = strlen(mystr);

转换操作符是一种特殊的类成员函数。它定义将类类型值转换为其他类型值的转换。转换操作符在类定义体内声明,在关键字operator之后跟着转换的目标类型。转换操作符的通用形式为:

operator  type(); 

转换函数必须是成员函数,不能指定返回类型,且形参表必须为空。因为转换的目标类型已经出现在转换操作符中了,所以就不需要重复定义返回值类型了。

3. Conversion Operators in OpenCascade

OpenCascade中很多地方用到了转换操作符,如将生成的基本实体转换成其他拓朴类型时就用到了转换操作符,程序代码如下所示:

/* *    Copyright (c) 2014 eryar All Rights Reserved.
*
*           File : Main.cpp
*         Author : eryar@163.com
*           Date : 2014-04-12 18:02
*        Version : V1.0
*
*    Description : Learn Conversion Operators in OpenCascade.
*
*      Key words : OpenCascade, Conversion Operators
* */ #define WNT #include <BRepPrimAPI_MakeSphere.hxx> #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKBRep.lib") #pragma comment(lib, "TKPrim.lib") #pragma comment(lib, "TKTopAlgo.lib") void TestConversionOperators(void)
{TopoDS_Shape theSphereShape = BRepPrimAPI_MakeSphere(1.0);TopoDS_Solid theSphereSolid = BRepPrimAPI_MakeSphere(1.0);TopoDS_Shell theSphereShell = BRepPrimAPI_MakeSphere(1.0);TopoDS_Face theSphereFace = BRepPrimAPI_MakeSphere(1.0); // error C2440: 'initializing' : cannot convert // from 'BRepPrimAPI_MakeSphere' to 'TopoDS_Wire' //TopoDS_Wire theSphereWire = BRepPrimAPI_MakeSphere(1.0); } int main(int argc, char* argv[])
{TestConversionOperators(); return 0;
}

如上代码所示,可以将类BRepPrimAPI_MakeSphere自动转换成TopoDS_Shape, TopoDS_Solid, TopoDS_Shell, TopoDS_Face,但是不能自动转换成TopoDS_Wire。这是因为在其父类BRepPrimAPI_MakeOneAxis中定义这些转换操作符,代码如下所示:

//! The abstract class MakeOneAxis is the root class of <br> //! algorithms used to construct rotational primitives. <br> class BRepPrimAPI_MakeOneAxis  : public BRepBuilderAPI_MakeShape { public:DEFINE_STANDARD_ALLOC //! The inherited commands should provide the algorithm. <br> //!          Returned as a pointer. <br> Standard_EXPORT virtual Standard_Address OneAxis()  = 0; //! Stores the solid in myShape. <br> Standard_EXPORT virtual void Build() ; //! Returns the lateral face of the rotational primitive. <br> //! <br> Standard_EXPORT const TopoDS_Face& Face() ;
Standard_EXPORT operator TopoDS_Face(); //! Returns the constructed rotational primitive as a shell. <br> Standard_EXPORT const TopoDS_Shell& Shell() ;
Standard_EXPORT operator TopoDS_Shell(); //! Returns the constructed rotational primitive as a solid. <br> Standard_EXPORT const TopoDS_Solid& Solid() ;
Standard_EXPORT operator TopoDS_Solid(); protected: private:
};

由上述代码可知,当将BRepPrimAPI_MakeSphere赋值给TopoDS_Shape时,会调用operator TopoDS_Shape()转换操作符的转换函数;当赋值给TopoDS_Shell时,会调用operator TopoDS_Shell()转换函数,等等。未定义的转换类型是不允许自动转换的,如TopoDS_Wire。

使用这些转换操作符使不同类型之间的类型转换很自然直观,看上去就像调用了一个函数。

类型之间的转换当然还有其他方法,如给转换的目标类型增加一个构造函数来实现。但是使用构造函数来转换不能转换成基本类型,如int, double等;还有个不足之处就是要修改转换目标类的声明文件来增加一个构造函数。没有转换操作符来得自然,方便。

4. Conclusion

当需要在不同类型之间进行类型转换时,可以使用转换操作符(Conversion Operators)。使用转换操作符的方式别其他方法要简单直观。

由于OpenCascade中类型比较多,且经常需要要不同类型之间进行转换操作,所以将一些常用的转换定义成转换操作符还是很方便的。

5. References

1. Bjarne Stroustrup. The C++ programming language. Higher Education Press. 2009

2. Stanley B. Lippman, Josee Lajoie, Barbara E. Moo. C++ Primer. Addison Wesley. 2005

3. Martin Reddy. API Design for C++. Morgan Kaufmann. 2011

PDF Version: Conversion Operators in OpenCascade

转载于:https://my.oschina.net/eryar/blog/347857

Conversion Operators in OpenCascade相关推荐

  1. Visual C++ 2012编译器更新(预览版)发布

    详见 http://blogs.msdn.com/b/vcblog/archive/2012/11/02/visual-c-c-11-and-the-future-of-c.aspx 本次编译器更新主 ...

  2. 9.Methods(二)

    4.Operator Overload Methods allow a type to define how operators should manipulate instances of the ...

  3. Operator Overloading

    1.重载一元操作符 To declare a unary operator function as a nonstatic member, you must declare it in the for ...

  4. C++对象模型学习——站在对象模型的尖端

    2019独角兽企业重金招聘Python工程师标准>>> 这里要讨论三个著名的C++语言扩充性质,它们都会影响C++对象.它们分别是template. exception handli ...

  5. Type Casting

    Type Casting   C++ : Documents : C++ Language Tutorial : Type Casting   Search: user pass [register] ...

  6. 《Accelerated C++中文版》--- 读书笔记

    1. C++中同名函数嵌套,不一定都是递归,有可能是函数重载 [2010-07-24 22:14:25] 2. 避免单个语句产生多个副作用.因为当此句发生异常[异常本身是一种副作用,因为他产生了异常对 ...

  7. [C++]各编译器对C++11的支持比较

    各编译器对C++11的支持比较 转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2154 在KlayGE首次引入C++11特性之后,我顺便调研了 ...

  8. 隐式类型转换与转换操作符operator T

    隐式类型转换与转换操作符 operator T C++ 标准允许隐式类型转换,即对特定的类,在特定条件下,某些参数或变量将隐形转换成类对象 ( 创建临时对象 ) .如果这种转换代价很大 ( 调用类的构 ...

  9. Effective C# 摘录(3) - 使用C#表达设计

    19:定义并实现接口优于继承类型.    Prefer Defining and Implementing Interfaces to Inheritance.    接口支持多重继承,可以作用于值类 ...

最新文章

  1. 不需要懂得编程,但却可以使用ggplot2画出论文级别的图?
  2. 【ZooKeeper】配置文件详解
  3. 零基础Java学习之super关键字
  4. MFC内嵌web页面
  5. Request.ServerVariables 参数大全
  6. Xamarin效果第八篇之视频监控
  7. redis在php中的应用(string篇)
  8. 老吴做了15年电商,从简单的卖货,到卖供应链
  9. kotlin中List,Map,数组的使用
  10. 日志清理BAT脚本带输出日志
  11. uniapp微信小程序使用canvas自定义分享名片
  12. 鲁百年创新设计思维学习总结
  13. matlab做分数阶差分,分数阶微分方程数值实验MATLAB编码
  14. 今日头条阅读量怎么刷_今日头条推广 今日头条阅读量怎么刷
  15. canvas在PC端实现振幅大小可变的动态波浪图
  16. 学习《第一行代码》之实战项目-搜杰天气
  17. 【001】C++11允许匿名类型、局部类型作为模板实参
  18. C#生成含数字字母的随机字符串
  19. 计算机教室英语怎么读音,电脑教室,computer teaching room,音标,读音,翻译,英文例句,英语词典...
  20. 计算机考研如何寻找调剂信息?我这有最全的!

热门文章

  1. Linux进阶之软件管理
  2. Python面向对象基础一
  3. .Net页面中使用在线编辑框实例
  4. 格密码教程(四):SVP和CVP,Hermite定理,Blichfeld定理和Minkowski定理
  5. 测试丢包_入行游戏测试之弱网测试工具
  6. python上传文件 request_Python request post上传文件常见要点
  7. 如何让页面初始化的时候实现点击事件_辅助程序实现黑盒自动化测试的常见问题...
  8. SpringBoot三招组合拳,手把手教你打出优雅的后端接口
  9. 深入理解Java中的volatile关键字
  10. Jeecg 切换默认首页方法