类的自动传唤和强制类型转换

来源:互联网 发布:淘宝店铺出租风险 编辑:程序博客网 时间:2024/05/16 00:10

一、其他的类型自动转换为类的类型

    只有一个参数的类构造函数用于将类型与该参数相同的值转换为类的类型。不过,在构造函数声明中使用explicit可以防止隐式转换,而只允许显式转换。

 

定义如下的类:

--------------------------------------------------------

class Test
{
      private:
              double a;
              int b;
      public:
             Test(){a = 0.0 ; b = 0;}
             Test(double aa);
             Test(int bb);
             Test(double aa , int bb);
             void show()const;
};

Test::Test(double aa)
{
      std::cout<<"this is the construction functino for double!\n";
      a = aa;
      b = 0;
}

Test::Test(int bb)
{
      std::cout<<"this is the construction function for int\n";
      a = 0.0;
      b = bb;
}

Test::Test(double aa ,int bb)
{
      a = aa;
      b = bb;
}

void Test::show()const
{
     std::cout<<"a = "<<a<<" ; b = "<<b<<std::endl;
}

---------------------------------------------------------

 

   接下来,用如下的代码测试类:

double aa = 12.3;
int bb = 12;
Test t1 = aa;
t1.show();

Test t2 = bb;
t2.show();

 

    上面的代码就将aa隐式地自动转换为了Test类。在这个过程中,程序使用了构造函数Test(double aa)来创建一个临时的Test对象,并且以aa为参数。也可以这样写:Test t1 = 12.3;

    同样,对于t2也是如此,只是构造函数换成了Test(int bb)。

    注:只有接受一个参数的构造函数才能作为转换函数。因此,Test(double aa,int bb)就不能作为转换函数。

 

    以上的转换是隐式自动进行的,C++提供了关键字explicit来关闭这种自动型,从而要求强制显示转换。

只需要将构造函数的声明修改一下(函数定义中不用再使用explicit):

explicit Test(double aa);
explicit Test(int bb);

    这样就关闭了隐式的自动转换,但可以显示的转换:

    double aa = 12.3;
    int bb = 12;
    Test t1 = Test(aa);
    t1.show();
    Test t2 = Test(bb);
    t2.show();

 

二、类的类型转换为其他类型

   

    要实现这种转换,需要使用到转换函数: operator typeName()。例如: operator double()。

    注意:1.转换函数必须是类方法2.转换函数不能指定返回类型;3.转换函数不能有参数

 

将上面的类修改一下。

class Test
{
      private:
              double a;
              int b;
      public:
             Test(){a = 0.0 ; b = 0;}
             explicit Test(double aa);
             explicit Test(int bb);
             Test(double aa , int bb);
             void show()const;
             operator double()const;
             operator int()const;
};

Test::Test(double aa)
{
      std::cout<<"this is the construction functino for double!\n";
      a = aa;
      b = 0;
}

Test::Test(int bb)
{
      std::cout<<"this is the construction function for int\n";
      a = 0.0;
      b = bb;
}

Test::Test(double aa ,int bb)
{
      a = aa;
      b = bb;
}

void Test::show()const
{
     std::cout<<"a = "<<a<<" ; b = "<<b<<std::endl;
}

Test::operator double()const
{
     return a;
}

Test::operator int()const
{
     return b;
}

 

    这样,就可以进行如下的转换:

    Test tt(12.3,12);
    double aa = tt;
    int bb = tt;

或者:

    Test tt(12.3,12);
    double aa = double(tt);
    int bb = int(tt);

    当然,类在转换为其他的类型时要进行什么样的变化,可以根据用户需要修改对应的转换函数定义。将类对象赋给typeName变量或将其将至转换成typeName类型时,该函数将自动被调用。

    关键字explicit不能用于转换函数,因此只要定义了转换函数都可以隐式调用转换,因此,在很多不想实现转换的地方可能也会转换,例如,不小心将tt作为了数组的下标,char kk[tt],由于类型的转换而查不到错误。

因此,通常,类转换为其他类型时,都不适用转换函数,而是用户自定义一个需要显示调用的函数,类似于:

double Test_to_double()。

 

转换的过程允许先进行其他级别的转换。例如,如果没有定义Test(int bb)这个构造函数。如下语句也是可以运行的:

int bb = 12;

Test tt = bb;   //没有用explicit限制

 

这里bb将先被转换成double,再使用Test(double aa)转换成tt。

 

0 0