大胖的部落格

Just a note

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  112 随笔 :: 0 文章 :: 3 评论 :: 0 Trackbacks

有两种函数允许编译器进行隐式类型转换:
1、单参构造函数
2、隐式类型转换运算符

1、单参构造函数

#include "stdafx.h"
#include
<iostream>

using namespace std;


class Base
{
public:
    
//单参构造函数
    Base(int i=0)
    
{
        cout
<<"Base Construct: "<<i<<endl;
    }


}
;

//value
void TestValue(Base b)
{
    
//implicit type conversion
}


//const reference
void TestConstRef(const Base& b)
{
    
//implicit type conversion
}


//reference
void TestRef(Base& b)
{
    
//can not be called
}


int main(int argc, char *argv[])
{
    Base b;

    
//发生隐式类型转换,调用单参构造函数
    TestValue(3);
    TestConstRef(
4);

    
//error
    
//TestRef(5);

    
return 0;
}



输出:
Base Construct: 0
Base Construct: 3
Base Construct: 4
**********************
后两个输出就是发生隐式类型转换时,调用单参构造函数输出的。
参数为传值或const引用会发生隐式类型转换,生成临时对象;传引用不会。

通过在函数声明前使用explicit,可以避免调用单参构造函数发生隐式类型转换。
//在函数声明前使用explicit关键字
explicit Base(int i=0)

//error C2664: 'TestBase' :cannot convert parameter 1 from 'int' to 'Base'
    TestBase(3);

也可以通过使用proxy class,来避免调用单参构造函数发生隐式类型转换。
#include<iostream>

using namespace std;


class Base
{
public:
    
//proxy class,用来构造Base
    class BaseValue
    
{
    
public:
        BaseValue(
int i):value(i)
        
{
            cout
<<"proxy class construct: "<<value<<endl;
        }


        
~BaseValue()
        
{
            cout
<<"proxy class destruct"<<endl;
        }


        
int value;
    }
;

    
//使用proxy class来构造Base
    Base(BaseValue bValue)
    
{
        cout
<<"Base construct: "<<bValue.value<<endl;
    }

}
;

//传入参数为Base类型
void TestBase(Base b)
{
    
}


int main(int argc, char *argv[])
{
    
//先用int构造一个临时的proxy class对象,再用proxy class对象构造Base
    Base b(3);

    cout
<<sizeof(Base)<<endl;                //1
    cout<<sizeof(Base::BaseValue)<<endl;    //4

    
//error C2664: 'TestBase' : cannot convert parameter 1 from 'int' to 'Base'
    
//TestBase(4);

    
return 0;
}



输出:
proxy class construct: 3
Base construct: 3
proxy class destruct
1
4
************************
临时的proxy class对象在Base的构造函数退出时销毁。
Base的成员中没有proxy class对象,所以proxy class不影响Base的大小。
当构造Base对象时,会需要一个BaseValue对象,编译器会发现用int可以构造BaseValue对象,所以进行1次隐式类型转换(从int到BaseValue),这是允许的。
但当函数调用时发现需要的是Base类型,现在只有int类型,需要连续两次用户定义的类型转换,int->BaseValue->Base,这是被禁止的。



2、隐式类型转换符:
#include<iostream>

using namespace std;


class Base
{
public:
    
//将Base转换为int
    operator int() const
    
{
        cout
<<"operator int() called"<<endl;
        
return 1;
    }

}
;

//传入参数为Int类型
void TestInt(int i)
{
    
}


int main(int argc, char *argv[])
{
    Base b;

    
//调用隐式类型转换符
    TestInt(b);

    
return 0;
}


posted on 2009-05-15 11:31 大胖 阅读(291) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理