C++中的类型转换与类型识别 1

 

C++ 基础内容, 不值一提

AuthorJacky Wu       2006-4-17

引用该文章,须注明其出处           http://blog.csdn.net/imwkj

 

3C++中的类型转换与类型识别

C++中类型转换有很多,从简单的内部类型的自动转换到复杂的自定义类的类型转换,以及多态方式的“类型转换”越来越复杂,让我等小辈看的是眼花缭乱,不得已,花点时间理清思路,以后用起来也方便一些。

很多书中对于类型转换都有分散介绍,大概在类继承,多态,以及运行时刻类型识别(RTTI)这些章节有叙述,我对此理解也并不是很透,只能试验几个代码,理清一些思路,当然会有理解错误的地方,还望各路高手多做指点,我在这先谢了。

 

1:内部类型转换

内部类型的转换很好理解,一般都会碰到。从char -> int -> float ->double等等,在这种情况下,如果是从字节数小的类型转换到大的类型一般不会出现错误

(如int ->float),但是反过来就会有问题了(float - > int)这会丢失一些数据得到部准确的结果,编译器也会在这种情况下发出警告。当然,可以用强制类型转换来肯定我们的操作:

    int i = 100;

    float x  = 2.0;

    x = i; //ok,缺省转换没有问题

    i = x; //可以这样做,但会引起警告

 

    i =(int) x;   //OK,正确的操

    /* 对于这样的强制转换,可以有很多种方式,主要是同根类型之间的转换

     * 内部类型到内部类型,指针到指针,引用到引用

     * 使用时当然要注意转换后数据的正确性

     */

还有进行运算时的隐式转换,方式同上面一样,主要式类型提升转换,这很简单的说J

 

2:自定义类型的自动类型转换,有两种方式

a. 利用构造函数自动转换

b. 利用自定义operator ?? 定义转换类型

  a. 利用构造函数自动转换

这种方法是通过构造函数把另外一个类型的对象或者引用作为参数,通过这样的方式来实现参数类型到构造类型之间的转换(好像没有表达清楚),咱们看代码:

 

class AC {

public:

    AC() {}

};

class BC {

public:

    BC( const AC& a ) {      //注意构造函数的参数类型

       cout << " Invoke BC ( const AC& a )" << endl;

    }

};

void fun( BC ) {  //注意函数传递的参数类型

    cout << "invoke fun(BC) " << endl;

}

int main() {

    AC aclass;

    fun(aclass);  //注意输入的参数类型

}

 

输出结果

Invoke BC( const AC& a )

invoke fun(BC)

 

显然,在调用 fun(aclass); 的时候,自动通过调用 BC的构造函数生成了BC对象,这样就可以正确使用这个函数,但是如果参数是通过引用传递的:void fun( BC& ),上诉做法就会出现错误。如果想避免出现这样的隐式调用,则使用 explicit关键字:

class BC {

public:

    explict BC( const AC& a ) {     //注意构造函数的参数类型

       cout << " Invoke BC ( const AC& a )" << endl;

    }

};

这样,上述的隐式转换就不会成功。

 

b. 利用自定义operator classname 定义转换类型

通过operator关键字创建一个成员函数,关键字后面跟上想要转换的目的类型,这样就可以实现将当前类型转换到目的类型:

class Three {

public:

    Three(int sz = 0) : size(sz) {

    cout << "Invoke Three(int sz = 0)" << endl;

}

private:

    int size;

};

 

class Four {

public:

    Four(int sz ): size(sz) {      

       cout << "Invoke Four(int sz )" << endl;

    }

    operator Three() const {

       cout << "Invoke Four::operator Three() " << endl;

       return Three(size);

       //由于类 Three Four之间的关联性,它们之间的转换是可行的    

    }

private:

    int size;

};

 

void fun( Three ) {  //注意函数传递的参数类型 同样参数不可以是引用

    cout << "invoke fun(Three) " << endl;

}

int main() {

    Four four(1);

    fun(four); //通过调用 operator Three() 进行类型转换

    fun(1);    //同样是自动类型转换,通过构造函数 int Three

}

输出结果:

Invoke Four(int sz )

Invoke Four::operator Three()

Invoke Three(int sz = 0)

invoke fun(Three)

Invoke Three(int sz = 0)

invoke fun(Three)

显然通过自定义的operator Three() 实现了由 Three Four之间的转换。

自动类型转换的问题:

自动类型转换由于是由编译器隐式调用的,有很多细节我们不是很清楚,在使用这个功能的时候要格外小心,下面两种情况会出现问题:(copy from thinking in c++

class Orange ; //class declaration

 

class Apple {

public:

    operator Orange() const {}  //自定义转换

}

class Orange {

public:

    Orange(Apple);    //构造转换

};

void fun( Orange ) {}

 

int main() {

    Apple ap;

    // fun (a);   //狂晕,到底是调用Apple::operator Orange ()

              //还是Orange::Orange(Apple),显然,编译器会认为有冲突

}

 

还有,当类自定义了到多个类型的转换时,就不能进行下面的重载:

class Orange {};  //class declaration

class Pear {};

class Apple {

public:

    operator Orange() const {}  //自定义转换

    operator Pear() const {] //另外一个转换

}

 

//重载fun

void fun( Orange ) {}

void fun(Pear) {}

 

int main() {

    Apple ap;

    // fun(a); //实在狂晕,到底是调用想怎么转换

              //不论怎么转换,都使得fun的重载是错误的

}

很明显,自动类型转换不是太好用的东东,我们必须在确定需要它的时候在使用它,而且必须确保无误,否则会很难调试,待续...

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值