当一个类含有转换运算符重载函数的时候,有时候会破坏C++原有规则,导致运算效率降低,这一点不得不注意。
示例如下:
|
按照C++对无名对象的约定,Test b=Test(99);C++是会按照Test b(99);来处理的,可是由于转换运算符的加入,导致这一规律被破坏,系统会“错误的”认为你是要给对象赋值,所以系统首先利用Test(99)创建一个临时对象用于赋值过程使用,可是恰恰系统又没有使用自动提供的赋值运算重载函数去处理,因为发现b对象并未构造,转而又不得不将开始原本用于赋值而创建的临时对象再次的强转换为int类型,提供给b对象进行构造,可见中间的创建临时对象和载入转换运算符函数的过程完全是多余,读者对此例要认真解读,充分理解。
由于类的转换运算符与类的运算符重载函数,在某些地方上使用的时候,有功能相似的地方,如果两者都存在于类中,那么虽然运行结果正确,但其运行过程会出现一些意向不到的步骤,导致程序运行效率降低。
下面的例子就是这个情况,代码如下:
| 现在总结一下转换运算符的优点与缺点:
优点:在不提供带有类对象参数的运算符重载函数的情况下,转换运算符重载函数可以将类对象转换成需要的类型,然后进行运算,最后在构造成类对象,这一点和类的运算符重载函数有相同的功效。(例2就是这种情况)
缺点:如果一个类只有转换运算符重载函数,而没有真正意义上运算符重载函数,当用转换运算符重载函数替代运算符重载函数,进行工作的时候,就会让程序的可读性降低,歪曲了运算符操作的真正含义。(例2中的c=a+b;//隐式转换,就是例子,事实上a+b的作用只是对返回的整型数据进行了加运算,而对象赋值的操作是系统隐式的帮大家转换成了c=Test(a+b)。)
最后我们来说一下,多路径转换的多义性问题,多义性问题一直是C++编程中容易忽视的问题,但它的确是不容小视,当问题隐藏起来的时候你不会发觉,一旦触发麻烦就来了。
类的转换构造函数与类的转换运算符重载函数是互逆的。(例3中的Test(int a = 0)是将int类型的数据转换构造成Test类对象,而operator int()则是将Test类对象转换成int类型数据)
但是当他们是出现在两个不同的类中,对于一个类对象转换来说,同时拥有两种近似的转换途径的时候,多义性的问题就暴露出来,导致编译出错。
下例就是这个状态:
|
代码中的A at=A(bt);运行正常,因为系统发现对象at还未构造,所以优先选取了A类的转换构造函数处理了,没有产生二义性问题。 但是代码中的tp(bt);编译错误,这是因为函数tp的参数要求的是一个A类对象,而我们给他的则是一个B类对象,而在A类与B类中都有一个类似的操作,可以将B类对象转换成A类对象,系统不知道是选取A类的转换构造函数进行构造处理,还是选择B类中的转换运算符号重载函数处理,系统拒绝从他们两个中选一个,所以编译错误。 我们修改tp(bt)为tp(A::A(bt));编译正常,因为我们显式的明确的告诉系统应该使用A类的转换构造函数处理,所以,显式的告诉计算机应该如何处理数据,通常可以解决多义性问题。 |