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 ;
}

如上代码所示,可以将类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() = ;
//! 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

Conversion Operators in OpenCascade的更多相关文章

  1. Advanced C++ | Conversion Operators

    In C++, the programmer abstracts real world objects using classes as concrete types. Sometimes it is ...

  2. LINQ 学习路程 -- 查询操作 Conversion Operators

    Method Description AsEnumerable Returns the input sequence as IEnumerable<t> AsQueryable Conve ...

  3. [c++] Operator overloading

    c++的操蛋属性:自己为一档,空一档,其他随意. UB_stack a; UB_stack b = a; // copy auto c = a; auto d {a}; // (or auto d = ...

  4. Google C++ Style Guide

    Background C++ is one of the main development languages used by many of Google's open-source project ...

  5. CLR via C# 3rd - 08 - Methods

       Kinds of methods        Constructors      Type constructors      Overload operators      Type con ...

  6. CLR via C# 3rd - 06 - Type and Member Basics

    1. Different Kinds  of Type Members        A type can define zero or more of the following kinds of ...

  7. C++的隐式类型转换与转换操作符

    C++标准允许隐式类型转换,即对特定的类,在特定条件下,某些参数或变量将隐形转换成类对象(创建临时对象).如果这种转换代价很大(调用类的构造函数),隐式转换将影响性能.隐式转换的发生条件:函数调用中, ...

  8. C#复习④

    C#复习④ 2016年6月16日 12:37 Main Classes and Structs 类和结构体 1.Contents of Classes 字段,常量,方法,构造函数,析构函数: 特性,事 ...

  9. (转)C++0x语言新特性一览

    转自:http://blog.csdn.net/zwvista/article/details/2429781 原文请见http://en.wikipedia.org/wiki/C%2B%2B0x. ...

随机推荐

  1. Leetcode Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...

  2. linux菜鸟日记(5)

    iptables详细语法及配置: SNAT:源地址转换DNAT:目标地址转换PNAT:端口地址转换 ----------------------------------iptables规则链 路由以后 ...

  3. 20161022 NOIP模拟赛 T1 解题报告

    旅行者问题 [问题描述] lahub是一个旅行者的粉丝,他想成为一个真正的旅行者,所以他计划开始一段旅行.lahub想去参观n个目的地(都在一条直道上).lahub在起点开始他的旅行.第i个目的地和起 ...

  4. JSPatch 中 defineClass 中覆盖方法的使用

    今天研究了一下JSPatch,发现好神奇好奇妙,感觉这几天我都会乐此不彼的去研究这个高大上的东西. 出处来着:https://github.com/bang590/JSPatch 简单介绍一下这个 d ...

  5. 日常关键字:定时关机、该任务映像已损坏或已篡改.(0x80041321)、ChaZD生词同步扇贝

    我在床上用chinanet网络慢得简直令人发指,12B/S.是的你没有看错,这是我最常看到的网速.但是我最近发现电脑联网开出一个WiFi,在床上用手机上网时,网速会一点提升,可达到1KB/S(⊙﹏⊙) ...

  6. [IOS]swift 使用AVOS的API

    避免写后台代码,但保证app能够有后台,使用了AVOS这个产品来帮助自己的app联网,AVOS是很强大的云服务,基本原理和Parse差不多,只是parse在国外可能对国内用户联网速度上有点限制. 下面 ...

  7. SQL语句操作数据与一些函数使用的丰富数据库

    数据库有多重要,其实不用我说,但该怎么运用好数据库下SQL语句与其它的如“函数”等等,那就需要我们大家多多去练习并总结其中的窍门,或许你的总结没那么好,担只要你的练习足够多,就算那不是窍门,那也将是你 ...

  8. 第三方框架之ThinkAndroid 学习总结(一)

    ThinkAndroid是一个免费的开源的.简易的.遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单.快速的进行Android应用程序的开发,包含Android mvc.简易s ...

  9. WebView解析

    WebView解析   WebView是一个基于Webkit的,相当于内置浏览器的强大功能的组件,WebView的使用这么分四步说明:添加组件,加载资源,属性设置,辅助功能. 一.WebView的添加 ...

  10. 用jdbc访问二进制类型的数据

    package it.cast.jdbc; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...