分享

c++转换构造函数与类型转换函数

 quandsu 2013-08-16
转换用户定义的类类型,必须由用户告知。用户告知的方式就是定义含一个参数的构造函数。
    例如,下面的代码中定义了学生类的构造函数:
class Student
{
public:
    Student(char*);
};
void fn(Student s);
int main()
{
    fn("Jenny");
    return 0;
}
    这里Student(char*)构造函数同时也在告知,如何将char*转换成一个Student对象。如果有重载函数fn(char*),则调用fn("Jenny")马上匹配了事。但就是因为没有这样的重载函数,所以C++对所有fn函数进行类型转换试探,包括构造函数。
    因为为Student(char*)的构造函数,又有fn(Student& s)函数,于是fn("Jenny")便被认为是fn(Student("Jenny")),最终予以匹配。把构造函数用来从一种类型转换为另一种类型,这是C++从类机制中获得的附加性能。但要注意下面两点:
    (1)只会尝试含有一个参数的构造函数;
    (2)如果有二义性,则放弃尝试。例如:
class Student
{
public:
    Student(char* pName = "no name");
};
class Teacher
{
public:
    Teacher(char* pName = "no name");
};
void addCourse(Student s);
void addCourse(Teacher t);
int main()
{
    addCourse("Prof.Dingleberry"); // error:二义性
    return 0;
}
    改正的方法是,只要显式转换一下:
addCourse(Teacher("Prof.Dingleberry"));


 一个类型转换函数的例子:
#include <iostream.h>

class date
{
public:
    date(int a, int b);
    operator int();//类型转换函数
    void output(void);
    date &operator=(int);//重载等号运算符
private:
    int  str;
    int  mimg;
};

date::date(int a, int b)  //构造函数
{ str = a;
  mimg = b;
}

date::operator int()   //类型转换函数,将date类型转换为int类型
{
  return str;
}

void date::output(void)
{
    cout << str << "  " << mimg << endl;
    return;
}

date &date::operator=(int i)
 {
    str=i;
    mimg=1000;
    return *this;
 }

int main(void)
{

   date da(100, 200);

   date c(0,0);
    //int c;
   c = 55 + da;
   c.output();//结果为 155  1000
    //cout<<c;//结果为 155
    return 0;
}
其中main函数中的c = 55 + da;若定义c为int型(如注释),则编译器首先判断等号左端的c为int类型,则须将等号右端的da用类型转换函数转换为int型,然后相加,返回int型结果。若定义c为date类型,则须将等号右端的55+da转换为date类型,但是又没有转换构造函数把常量55转为date型,也没有重载+号运算符,只能用类型转换函数将da转为int型,55+da的结果就是一个int型。但等号右端的c却为date型,等号两端类型不匹配,所以就通过重载的=号运算符,隐式调用c.operator(55+100),由于重载的=号运算符返回是一个引用类型,所以c.operator(55+100)的结果就是还是date类型的c。本程序中的c = 55 + da的调用过程是:c.operator(55+(da.operator int())).
再写一个转换构造函数的例子
#include <iostream.h>

class date
{
public:
    date(int a, int b);
    date(int n); //转换构造函数
    friend date  operator+(const date &,const date &); //重载 + 
    void output(void);
    date &operator=(int);
private:
    int  str;
    int  mimg;
};

date::date(int a, int b) //构造函数
{ str = a;
  mimg = b;
}

date :: date(int n)   //转换构造函数
{
    str = n;
    mimg = 0;
}

date  operator +(const date &a,const date &b) //重载 +
{
    return date(a.str + b.str, a.mimg + b.mimg);
}

void date::output(void)
{
    cout << str << "  " << mimg << endl;
    return;
}

int main(void)
{
   date da(100, 200);
   date c(0,0);
   c = 55 + da;
   c.output();
    return 0;
}
main函数在执行c=55+da时,判断c为date类型,所以(55+da)也应为data类型。通过转换构造函数将根据55,创建一个date类型的一个临时对象,然后通过+号运算符重载函数,计算da与临时对象的和。但这里需要注意,+号运算符重载函数里的参数必须是const类型。因为非const的引用只能绑定同类型的对象,const则可以绑定能互相转换的类型。即隐式转换不会被用于非const的引用参数。


一个二义性的例子:
#include <iostream.h>

class date
{
public:
    date(int a, int b);
    date(int n);        //转换构造函数
    operator int();     //类型转换函数
    friend date  operator+(const date &,const date &);   //重载 + 
    void output(void);
    date &operator=(int);
private:
    int  str;
    int  mimg;
};

date::date(int a, int b)  //构造函数
{ str = a;
  mimg = b;
}

date :: date(int n)      //转换构造函数
{
    str = n;
    mimg = 0;
}
date::operator int()   //类型转换函数
{
  return str;
}

date  operator +(const date &a,const date &b) //重载 +
{
    return date(a.str + b.str, a.mimg + b.mimg);
}

void date::output(void)
{
    cout << str << "  " << mimg << endl;
    return;
}

int main(void)
{
   date da(100, 200);
   date c(0,0);
   c = 55 + da;
   c.output();
    return 0;
}
如果写成这样,那么main函数在执行c=55+da的时候就会出现二义性,不知道该调用类型转换函数还是调用转换构造函数了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多