C++构造函数、explicit、类合成

只有一个成员变量的类

当只有一个成员变量时,有一些不太注意的缺省转换发生,这是编译器造成的。
#include <iostream>
#include <cstdlib>
using namespace std;

class classA {
    int x;
public:
    classA(int x) { this->x = x; }
    classA(char *x) { this->x = atoi(x); }
    int getX() { return x; }
};

int main ( )
{
    classA ca(5);    //正常调用构造函数
    cout << "x = " << ca.getX() << endl;

    ca = 100;        //缺省调用classA(100)
    cout << "x = " << ca.getX() << endl;

    ca = "255";      //缺省调用classA("255")
    cout << "x = " << ca.getX() << endl;

    return 0;
}
运行结果:
x = 5
x = 100
x = 255

用explicit禁止默认转换

默认转换带来一定的方便,同时也造成不必要的失误,为了防止失误,可以在构造函数前加“explicit”。
#include <iostream>
#include <cstdlib>
using namespace std;

class classA {
    int x;
public:
    explicit classA(int x) { this->x = x; }
    explicit classA(char *x) { this->x = atoi(x); }
    int getX() { return x; }
};

int main ( )
{
    classA ca(5);    //正常调用构造函数
    cout << "x = " << ca.getX() << endl;

    ca = 100;        //编译出错
    cout << "x = " << ca.getX() << endl;

    ca = "255";      //编译出错
    cout << "x = " << ca.getX() << endl;

    return 0;
}
运行结果:
x=5

类的合成

当一个类的成员变量的类型是另一个类时,称之为“合成(composite)”。构造函数在对这个变量赋值时,不能在函数体里面赋值,只能用“第6节”中的方法2,即创建时赋值。
#include <iostream>
using namespace std;

class classB {
    int x;
public:
    classB(int x) { this->x = x; }
    int getB() { return x; }
};

class classA {
    classB xb;
public:
    //classA(classB b) { xb = b; }    //编译出错
    classA(classB b) : xb(b) { }     //只能用这种方法
    int setX() { return xb.getB(); }
};

int main ( )
{
    classB cb(5);    //先定义一个classB的实例
    classA ca(cb);  //然后用这个实例创建classA的实例
    cout << "x = " << ca.getX() << endl;

    return 0;
}
运行结果:
x=5