C++转型构造函数

在前面,我们已经将构造函数划分为两类:默认构造函数(不带参数的构造函数)和带参构造函数。其中带参数的构造函数中有两种比较常见的构造函数:拷贝构造函数和转型构造函数。我们先来了解一下转型构造函数。

转型构造函数用于类型间的转换,将其它数据类型转变为类的对象类型。转型构造函数只有一个参数,如果该参数是 int 型,则我们是将 int 型对象转换为类对象,如果该参数类型为 char * 类型,我们则是将字符串常量转换为类对象。

【例 1】
class Age
{
public:
    Age(int a){age = a;}
private :
    int age;
}
本例中,Age(int a) 即为一个转型构造函数,该构造函数仅有一个参数,该构造函数是将 int 型转换为类对象类型的。

【例 2】
class student
{
public:
    student(){}
    student(char * n){name = n;}
private :
    char * name;
}
在本例中,student 类中有两个构造函数,一个是默认构造函数,另一个是转型构造函数,该构造函数将字符串常量转换为类对象类型。

假设我们在程序设计过程中有一个以类对象作为函数参数的函数,函数声明如下:
void fun(student s); //函数声明
如果我们设计了如下程序以调用该函数:
char * name = “Harry Potter”;
fun(name);
在例 2 中,我们恰好在 student 类中定义了student(char * n);这样一个转型构造函数 ,该函数可以将字符串常量转换为 student 类的对象。在我们运行fun(name);语句时,编译器会自动调用转型构造函数将 name 转换为 student 类的对象,然后调用void fun(student s);函数。这一系列的过程都是编译器自动完成的,我们称此时的 student 类的转型构造函数student(char * n);支持隐式类型转换。

之所以说是隐式的,是因为这个转型过程完全由编译器完成,无需程序设计人员显示转换类型。

隐式类型转换给程序设计人员带来了一定的便利,但是隐式类型转换可能会给我们设计的程序带来一些难以觉察的细微错误。有时候我们为了避免这种错误,我们希望直接强制关闭掉这种隐式类型转换,在 C++ 中,通过关键字 explicit 可以实现该功能。

例3:
class student
{
public:
    student(){}
    explicit student(char * n){name = n;}
private :
    char * name;
}
如例 3 所示,我们在转型构造函数前加上了 explicit 关键字,如此一来,我们再想通过以下语句:
char * name = “Harry Potter”;
fun(name);
调用void fun(student s);函数则是无法通过编译的,因为 fun() 函数的参数是 student 类的对象而非字符串常量,并且 student 类的转型构造函数被标记为 explicit,因此无法隐式地将字符串常量转换为 student 类对象。使用 explicit 关键字的好处就在于将难以察觉的后期运行时可能会出现的错误提前到了编译期,如此一来改正错误就比较容易了。