C++转换构造函数(详解版)

一个构造函数接收一个不同于其类类型的形参,可以视为将其形参转换成类的一个对象。像这样的构造函数称为转换构造函数

除了创建类对象之外,转换构造函数还为编译器提供了执行隐式类型转换的方法。只要在需要类的类型值的地方,给定构造函数的形参类型的值,就将由编译器执行这种类型的转换。

举一个简单的例子,先来看下面这个类:
class IntClass
{
    private:
        int value;
    public:
        //转换int的转换构造函数
        IntClass(int intValue)
        {
            value = intValue;
        }
        int getValue() const { return value; }
};
由于构造函数 IntClass(int) 只接收一个类型不同于 IntClass 的单个形参,所以它是一个转换构造函数。

只要上下文需要类对象,但提供的却是构造函数形参类型的值,则编译器将自动调用转换构造函数,这会在以下 4 种不同的上下文环境中出现:
  • 该类的一个对象使用转换构造函数的形参类型的值进行初始化。例如:

IntClass intObject = 23;

 
  • 该类的一个对象被赋给了一个转换构造函数形参类型的值。例如:

intObject = 24;

 
  • 函数需要的是该类的类型的值形参,但传递的却是构造函数的形参类型的值。例如,假设定义了下面这样一个函数:
void printValue(IntClass x)
{
    cout << x.getValue();
}
但是在调用它的时候却传递了一个整数给它:

printValue(25);

编译器将使用转换构造函数将整数 25 转换为 IntClass 类的对象,然后将该对象传递给该函数。如果形参是一个指针或对 IntClass 对象的引用,则编译器将不会调用转换构造函数。只有在形参按值传递时,才会调用转换构造函数。

  • 声明类的类型的返回值的函数实际上返回的却是转换构造函数的形参类型的值。例如,编译器将接收以下函数:
IntClass f(int intValue)
{
    return intValue;
}
请注意,虽然已经将 IntClass 声明为其返回类型,但是该函数仍然会返回整数类型的值,于是编译器也将再次隐式地调用转换构造函数,将整数 intValue 转换为一个 IntClass 对象,这个对象正是需要从函数返回的对象。

以下程序演示了转换构造函数的操作。
Convert.h的内容
#include <iostream>
using namespace std;

class IntClsss
{
    private:
        int value;
    public:
        //Convert constructor from int
        IntClass(int intValue)
        {
            value = intValue;
        }
        int getValue() const { return value; }
};

//Convert.cpp 的内容
#include "Convert.h"
IntClass f(int intValue)
{
    return intValue;
}
void printValue(IntClass x)
{
    cout << x.getValue();
}
//mian函数
//This program demonstrates the action of convert constructors.
#include "Convert.h"
// Function prototypes.
void printValue (IntClass);
IntClass f(int);
int main()
{
    // Initialize with an int
    IntClass intObject = 23;
    cout << "The value is " << intObject.getValue() << endl;
    // Assign an int
    intObject = 24;
    cout << "The value is " << intObject.getValue() << endl;
    //Pass an int to a function expecting IntClass
    cout << "The value is ";
    printValue(25);
    cout << endl;
    // Demonstrate conversion on a return
    intObject = f(26);
    cout << "The value is ";
    printValue(intObject);
    return 0;
}
程序输出结果:

The value is 23
The value is 24
The value is 25
The value is 26

只要从某些类型自动转换为类的类型是有意义的,那么就应该考虑使用一个转换构造函数。在 C++ string 类中可以找到使用转换构造函数的实用示例。string 类提供一个将 C 字符串转换为 string 的转换构造函数:
class string
{
    //仅显示转换构造函数
    public:
        string(char *);
};
该转换构造函数的存在允许程序员将 C 字符串传递给需要 string 对象形参的函数,将 C 字符串赋值给 string 对象,并使用 C 字符串作为 string 对象的初始值:
string str = "Hello";
str = "Hello There!";
在某种意义上,转换构造函数的工作方式与前面介绍的类型转换运算符刚好相反:类型转换运算符是将一个对象转换为其他类型的值,而转换构造函数则是将给定类型的值转换为类的对象。