C++ 学习笔记之---类的自动转换

参考自《C++ Primer Plus 6th Edition》

 

类的自动转换:

 

说明:    C++允许程序员指定类之间进行转换的方式(含基本类型)

           站在类的角度看问题,姑且分为“当前类” 和 “其他类” 

假设:    当前类是程序员定义的,其他类既可以是程序员定义的,也可以是C++内置的基本类型

方式:    通过定义 “转化函数”

 

1. 其他类转换为当前类

 

转化函数:  

  本质: 允许只传入一个实参的构造函数

  包括:

    1. 只接受一个参数的构造函数

    2. 具有多个形参,但是在类的声明中,存在一个参数没有默认值,但是其他行参都有默认

      值的构造函数

 

那么,这里的 “其他类” 指的就是那个在类声明中没有设置默认值的类型,或者能够与这个类型自动转换的类型

 

 

有了转换函数之后呢,我们可以通过自动地将这个 “其他类” 的对象转换为 “当前类” 的对象 

 

举一个例子,实现了内置类型 int (“其他类”) 到Student类 (“当前类”) 的转换

#include <iostream>
using namespace std;

class Student
{
private:
    int id;
public:
    Student() {
    }
    Student(int ID) {
        id = ID;
    }
};

int main() {
    Student a = Student(1);        //explicit
    Student b(2);                //explicit
    Student c = 3;                //implicit
    return 0;
}
View Code

 

再举一个例子 (double 和 int 类型是可以互相自动转换)

#include <iostream>
#include <string>
using namespace std;

class Student
{
private:
    int id;
public:
    Student() {
    }
    Student(int ID , string name="") {
        id = ID;
    }
};

int main() {
    Student a = Student(1);        //explicit
    Student b(2.5);                //explicit
    Student c = 3.7;            //implicit
    return 0;
}
View Code

 

 

2. 当前类转化为其他类

 

“当前类” 转化为 “其他类” 就稍微麻烦点。因为,它的 “转换函数” 不是构造函数--需要额外定义

 

形式:  operator typeName();

要求:    1. 成员函数

     2. 不能指定返回类型      (即使如此,在实现时,你必须返回一个typeName类型的变量)

       3. 不能有参数       (其实有一个默认的参数--指向当前对象的this指针)

 

 

一个例子

#include <iostream>
using namespace std;

class Student
{
private:
    int id;
public:
    Student() {
    }
    Student(int ID) {
        id = ID;
    }
    operator int() {
        return id;
    }
};

int main() {
    Student student(5);
    cout << student << endl;
    return 0;
}
View Code

 

在上面这段代码中,含有语句 “cout << student << endl;”

为什么没有为 Student类 重载输出操作符函数,而编译器却没有报错呢?

因为,在输出的时候,Student对象student被自动转化为int类型的变量。而身为ostream对象的cout自然能处理int类型的变量

 

目前讲到的,“当前类”转换为“其他类”的例子里面,都是隐式类型转换,我们可以通过使用强制类型转换来使 “当前类” 转换为 “其他类”。

当然,在强制转换之前,我们也要像上面一样定义转换函数。

强制类型转换的句式我们也很熟悉了-- typeName (variable)  或  (typeName) variable

 

 

一些好的编程习惯:

 

1. 重载双目运算符时,定义为友元可以让程序更容易适应自动类型转换---两个操作数都成为了函数

    参数,因此与函数原型匹配 (就是有转换函数的意思)

    因为,如果操作数的类型不是当前类的类型,它可以通过 “转换函数” 转换为当前类的对象,再调

    用重载的运算符函数。

2. 自动转换的隐式转换,有时候会带来一些难以发现的问题。为了保险,可以使用显式转换,比如

    通过 explicit 来限定转换函数。

 

posted @ 2015-05-27 21:51  the_Gaven  阅读(845)  评论(0编辑  收藏  举报