用户名: 密码: 免费注册 忘记密码? 网站地图 | 加入收藏 | 设为首页
首页 | 新闻 | 工具 | 系统 | 办公 | 聊天 | 多媒体 | 网页 | 运营 | 平面 | 欣赏 | 数据库 | 程序 | 服务器 | 组网
网页 | 3dmax | Ghost | Windows Xp| Dreamweaver | photoshop | Flash | office | Alexa | Css | QQ | Asp | PHP | Jsp | Access
Flash MX 2004入门 | 网站推广策略 | CorelDRAW入门 | ASP学习 | 网站建设大师功 | Word入门
  iTbulo.com > 学院 > 正文
C++运算符重载转换运算符
iTbulo.COM 2006-4-5 管宁()

  由于类的转换运算符与类的运算符重载函数,在某些地方上使用的时候,有功能相似的地方,如果两者都存在于类中,那么虽然运行结果正确,但其运行过程会出现一些意向不到的步骤,导致程序运行效率降低。

  下面的例子就是这个情况,代码如下:

 C++ 代码 
 
//例4 
 
//程序作者:管宁         
//站点:www.cndev-lab.com         
//所有稿件均有版权,如要转载,请务必著名出处和作者      
   
#include <iostream>   
using namespace std;   
   
class Test     
{     
    public
        Test(int a = 0) 
        { 
            cout<<this<<":"<<"载入构造函数!"<<a<<endl; 
            Test::a = a; 
        } 
        Test(Test &temp) 
        { 
            cout<<"载入拷贝构造函数!"<<endl; 
            Test::a = temp.a; 
        } 
        ~Test() 
        { 
            cout<<this<<":"<<"载入析构函数!"<<this->a<<endl; 
            cin.get(); 
        } 
        Test operator +(Test& temp2) 
        { 
            cout<<this<<"|"<<&temp2<<"载入加运算符重载函数!"<<endl; 
            Test result(this->a+temp2.a);   
            return result;   
        } 
        operator int() 
        { 
            cout<<this<<":"<<"载入转换运算符函数的内存地址:"<<this->a<<endl; 
            return Test::a; 
        } 
    public
    int a; 
}; 
int main() 

    Test a(100),b(100); 
    cout<<"a的内存地址:"<<&a<<" | b的内存地址:"<<&b<<endl; 
    Test c=a+b; 
    cout<<"c的内存地址:"<<&c<<endl; 
    cout<<c.a<<endl; 
    system("pause"); 
}


  运行过程见下图。

  从图中我们可以清晰的看到,不必要的运算过程被执行,导致开销增大,读者在理解此例的时候要格外小心!

现在总结一下转换运算符的优点与缺点:

优点:在不提供带有类对象参数的运算符重载函数的情况下,转换运算符重载函数可以将类对象转换成需要的类型,然后进行运算,最后在构造成类对象,这一点和类的运算符重载函数有相同的功效。(例2就是这种情况)

缺点:如果一个类只有转换运算符重载函数,而没有真正意义上运算符重载函数,当用转换运算符重载函数替代运算符重载函数,进行工作的时候,就会让程序的可读性降低,歪曲了运算符操作的真正含义。(例2中的c=a+b;//隐式转换,就是例子,事实上a+b的作用只是对返回的整型数据进行了加运算,而对象赋值的操作是系统隐式的帮大家转换成了c=Test(a+b)。)

  最后我们来说一下,多路径转换的多义性问题,多义性问题一直是C++编程中容易忽视的问题,但它的确是不容小视,当问题隐藏起来的时候你不会发觉,一旦触发麻烦就来了。


  类的转换构造函数类的转换运算符重载函数互逆的。(例3中的Test(int a = 0)是将int类型的数据转换构造成Test类对象,而operator int()则是将Test类对象转换成int类型数据)

但是当他们是出现在两个不同的类中,对于一个类对象转换来说,同时拥有两种近似的转换途径的时候,多义性的问题就暴露出来,导致编译出错。

下例就是这个状态:
 C++ 代码 
 
//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream
using namespace std; 
class B; 
class A 

    public
        A(B &);//转换构造函数,他的作用是用B类对象构造A类对象 
        void Edita(int temp) 
        { 
            A::a=temp; 
        } 
    public
        int a; 
}; 
class B 

    public
        B(int a=0) 
        { 
            B::a=a; 
        } 
        int Ra() 
        { 
            return B::a; 
        } 
        operator A()//转换运算符重载函数,他的作用则是将B类对象转换成A类对象 
        { 
            return *this
        } 
    protected
        int a; 
}; 
A::A(B &temp) 

    cout<<this<<"|"<<&temp<<endl; 
    A::a=temp.Ra(); 

void tp(A temp) 

     

int main() 

    B bt(100); 
    A at=A(bt); 
    //tp(bt);//错误,多义性问题,系统不知道如何选择,是选择A(B &)转化构造好呢?还是选择B::operator A()进行转换好呢? 
    tp(A::A(bt));//显示的处理可以消除多义性问题 
    system("pause"); 
}


  代码中的A at=A(bt);运行正常,因为系统发现对象at还未构造,所以优先选取了A类的转换构造函数处理了,没有产生二义性问题。
  但是代码中的tp(bt);编译错误,这是因为函数tp的参数要求的是一个A类对象,而我们给他的则是一个B类对象,而在A类与B类中都有一个类似的操作,可以将B类对象转换成A类对象,系统不知道是选取A类的转换构造函数进行构造处理,还是选择B类中的转换运算符号重载函数处理,系统拒绝从他们两个中选一个,所以编译错误。
  我们修改tp(bt)为tp(A::A(bt));编译正常,因为我们显式的明确的告诉系统应该使用A类的转换构造函数处理,所以,显式的告诉计算机应该如何处理数据,通常可以解决多义性问题

上一页  [1] [2] 

文章搜索
相关资讯
相关文章 相关下载
C与C++中标准输入实现方式上的一点区别
将成员函数指针强制转换成void*指针
C与C++中标准输入实现方式上的一点区别
为C++标准库容器写自己的内存分配程序
缓冲区溢出还是问题吗?C++/CLI安全编码
焦点信息