首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

变换与类类型

2013-09-28 
转换与类类型转换与类类型今天看到CPrimer第14章9小节的转换与类类型,给我的感触是:类类型转换确实强

转换与类类型

转换与类类型

        今天看到<<C++Primer>>第14章9小节的转换与类类型,给我的感触是:类类型转换确实强大,但是却极易出错,很容易产生难以察觉的二义性,如非功力深厚,切记慎之。

        此文不打算讨论类类型转换问题,因为本人实在没怎么掌握,仅以此记住该书有此一难点,希望以后有幸深入探讨。

        虽然不讨论过于复杂的类类型转换的二义性问题及规避方法,但还是把手中的忠告罗列一下:

(1) 不要定义相互转换的类,如果类A中具有接受类B的对象的构造函数,不要再为类B定义到类型A的转换,即一种转换不要多种实现。

(2) 避免到内置算术类型的转换。具体而言,如果定义了到算数类型的转换,则:

1)   不要定义接受算术类型的操作符的重载版本。如果用户需要使用这些操作符,转换操作符将转换你所定义的类型对象,然后可以使用内置操作符。

2)   不要定义转换到一个以上的算术类型的转换。让标准转换提供到其他算术类型的转换。

总之:仅重载一个到内置类型的类型转换函数,其他转换交给标准转换;尽量不要实现类与类之间的转换;如果实现了类与类直接的转换最好不要重载算术操作符;在必要的地方进行显示类型转换总是一个绝好的选择。

 

在书中464页最后一段有这么一句描述:对于普通的成员函数,它是使用类的对象显示调用,或类的作用域显示调用,所以不会与非成员函数构成重载,即使名字参数完全相同;但是,对于操作符重载,调用本身不会告诉我们与使用的操作符函数作用域相关的任何事情,因此,成员操作符和非成员操作符版本能够构成重载。

以上描述貌似非常明确,其实不然,看看下面几个测试程序你就会明白了:

测试一:

#include<iostream>using std::cout;using std::endl; class Inter{public:    Inter(){}    Inter(int v):val(v){}    Inter& operator=(const Inter& r)    {       val = r.val;       return *this;    }    Inter& operator++()    {       ++val;       return *this;    }    Inter operator++(int)    {       Inter tmp = *this;       val++;       return tmp;    }    int getval()const{return val;}    int& reference(){return val;}private:    int val;}; Inter& operator++(Inter& r){    r.reference() += 1;    return r;} Inter operator++(Inter& r,int){    Inter tmp = r;    r.reference() += 1;    return tmp;} (4)/*Inter& operator++(){    return Inter(100);}*/  int main(){    Inter add(30);    (1)//cout<<(++add).getval()<<endl;    (2)//cout<<add++.getval()<<endl;    cout<<add.operator++().getval()<<endl;    cout<<add.operator++(0).getval()<<endl;    cout<<operator++(add).getval()<<endl;    cout<<operator++(add,0).getval()<<endl;    (3)//cout<<operator++()<<endl;}

(1)(2)的调用会产生二义性在前面已经解释过,后面就是函数式调用。明显不会出现二义性,至少作用域不同,参数个数也不同。后来企图用(3)测试是否是参数个数导致无二义性,但是失败了,原因在于(4)编译提示++操作符在类外定义至少需要一个类类型或者枚举类型的参数。

 

这么说来无法知道我们问题的答案了,那就先搁着把。

目测是作为函数调用其查找方式是按作用域的,二者不可能冲突,而作为操作符定义会有一些特殊的查找方式。

 

操作符查找规则(匹配规则):在C++中重载操作符有两种调用规则,一种就是把operator操作符当作普通函数使用,其匹配规则与普通函数无异;另一种用操作符特有的方式调用,如A+B,这样的话没有编译器任何关于操作符的作用域信息,此时编译器会同时在当前作用域及参数所在类域中查找。

 

 

 

 

热点排行