C11构造函数的改善

1、委托构造函数

  委托构造函数就是允许在同一个类中一个构造函数可以调用另一个构造函数,从而在初始化时简化变量的初始化。

class CTest
{
public:
    int x;
    int y;
    int z;

public:
    CTest(int a)
    {
        x = a;
    }

    CTest(int a, int b)
    {
        x = a;
        y = b;
    }

    CTest(int a, int b, int c)
    {
        x = a;
        y = b;
        z = c;
    }

    ~CTest(){}
};

  这个例子表明,在成员变量众多、变量的初始化比较复杂的情况下,构造函数的工作是重复且繁琐的,那么就可以通过委托构造函数来解决问题。

class CTest
{
public:
    int x;
    int y;
    int z;

public:
    CTest(int a)
    {
        x = a;
    }

    CTest(int a, int b) : CTest(a)
    {
        y = b;
    }

    CTest(int a, int b, int c) : CTest(a, b)
    {
        z = c;
    }

    ~CTest(){}
};

  这样优化之后,代码更加的简洁明了,但是这种链式调用不能形成一个环,否则会在运行时候抛异常。其次,使用了代理构造函数就不能使用类成员初始化了。

class CTest
{
public:
    int x;
    int y;
    int z;

public:
    //没有调用构造函数可以进行初始化
    CTest(int a) : x(a)
    {}

    //error:调用了构造函数不能进行初始化
    CTest(int a, int b) : CTest(a), y{b}
    {
    }

    //ok,调用了构造函数,可以在函数内部进行赋值
    CTest(int a, int b, int c) : CTest(a, b)
    {
        z = c;
    }

    ~CTest(){}
};

2、继承构造函数

  C++11的集成构造函数可以让派生类直接使用基类的构造函数,而无需自己再写构造函数,特别是基类构造函数比较多的情况下,可以极大的简化派生类构造函数的编写。

struct A
{
    int x;
    int y;
    //...其他成员
    
    A(int a) : x(a) {};
    A(int a, int b): x(a), y(b) {};
    //...其他构造函数
};

  如果派生类仅仅是增加基类某些行为,并没有增加变量,那么希望采取基类一样的构造方式,是不能直接使用基类的构造函数的,因为派生类会隐藏基类的同名函数。

struct B : public A
{
    //add do something
};

int main()
{
    B b(1, 2); //编译错误,没有合适的构造函数
    return 0;
}

  通过基类的构造函数去构造派生类的对象是不合法的,因为派生类的默认构造函数隐藏了基类,如果希望使用基类的构造函数,常规的做法是在派生类定义。

struct B : public A
{
    B(int a) : A(a) {};
    B(int a, int b): A(a, b) {};
    //...其他基类构造函数
};

  通过这个方法解决了和基类一样的构造行为,但是过程既繁琐又重复,C++11中解决了派生类隐藏基类同名函数的问题,通过using Base::SomeFunction来表示使用基类的同名函数,如果是构造函数,使用using Base::Base来声明使用基类的构造函数,这样就避免了定义相同的构造函数来保持和基类一样的初始化行为,使用基类的构造函数来构造派生类对象。但是需要注意的是,集成构造函数不会去初始化派生类新定义的数据成员。

struct B : public A
{
    //基类构造函数
    using A::A;
    
    //基类其他函数
    using A::SomeFunction;
};
原文地址:https://www.cnblogs.com/ChinaHook/p/7788934.html