[C++11] 理解委托构造函数

说明:委托构造函数是 C++11 引入的一种特殊类型的构造函数,它通过调用同一个类中的另一个构造函数来初始化对象。这种构造函数在声明时使用 : 符号后跟其他构造函数的初始化列表,而不是在函数体内调用。委托构造函数的主要目的是避免代码重复,并简化多个构造函数之间的共同初始化逻辑。以下是一个简单的委托构造函数的示例:

class MyClass {
public:
    // 基本构造函数,接受两个参数
    MyClass(int a, double b) : a_(a), b_(b) {
        // 初始化成员变量 a_ 和 b_
    }

    // 重点:委托构造函数,使用一个参数初始化
    MyClass(int a) : MyClass(a, 0.0) {
        // 这里没有额外的初始化代码,因为它委托给另一个构造函数
    }

    // 另一个重载的构造函数,接受三个参数
    MyClass(int a, double b, std::string c) : a_(a), b_(b), c_(std::move(c)) {
        // 初始化成员变量 a_, b_ 和 c_
    }

private:
    int a_;
    double b_;
    std::string c_;
};

注意:这里所谓的性能提升本质上是减少了成员变量初始化的时间,在一些大型工程中,成员变量初始化往往是很大的,因此要做这样的优化。

1 为什么C++11 引入委托构造函数?

C++11 引入委托构造函数的原因主要包括以下几点:

  • 减少代码重复:委托构造函数允许一个构造函数调用同一个类中的另一个构造函数,这样可以避免在多个构造函数之间重复相同的初始化代码。
  • 提高代码清晰度:通过委托构造函数,可以将类的构造逻辑分解成更小的、更易于管理的部分,使得代码结构更加清晰。
  • 增强类的可维护性:当需要修改或扩展类的初始化逻辑时,委托构造函数使得只需在一个地方进行更改,而不是在多个构造函数中重复修改。
  • 支持类的灵活设计:委托构造函数提供了一种机制,使得派生类可以重用基类的构造函数,或者在派生类中重用其他构造函数的初始化逻辑。
  • 简化构造函数的重载:当类有多个构造函数时,委托构造函数可以简化这些构造函数的实现,特别是当某些构造函数共享相同的初始化步骤时。
  • 优化编译器的实现:编译器可以更有效地处理委托构造函数,可能会生成更优化的代码,尤其是在处理复杂的构造函数重载和模板类时。
  • 提高资源利用效率:委托构造函数可以减少不必要的资源分配和释放,尤其是在处理大型对象或资源密集型对象时,可以提高程序的执行效率。
  • 支持构造函数的继承:在多重继承的情况下,委托构造函数可以使得派生类继承并利用基类的构造函数,而无需手动复制初始化代码。

通过引入委托构造函数,C++11 提供了一种更加高效和灵活的方式来设计和实现类的构造逻辑,有助于提高代码的质量和可维护性。

2 委托构造函数使用详解

委托构造函数在 C++11 中的使用案例主要体现在简化类的构造函数实现,避免代码重复,特别是在处理具有多个构造函数的类时。以下是一些包含代码实现的案例。

2.1 基础委托构造函数

参考代码如下:

class MyClass {
public:
    // 默认构造函数
    MyClass() :MyClass(0) {}

    // 带参数的构造函数
    MyClass(int importantData) : importantData(importantData) {}

private:
    int importantData;
};

在这个案例中,MyClass 有两个构造函数,一个是默认构造函数,一个是接受一个 int 类型的参数。第一个构造函数通过委托给第二个构造函数来初始化 importantData

2.2 多重委托构造函数

参考代码如下:

class Person {
public:
    // 默认构造函数
    Person() : name("Unknown"), age(0) {}

    // 带名字的构造函数
    Person(const std::string& name) : name(name), age(0) {}

    // 带名字和年龄的构造函数
    Person(const std::string& name, int age)
        : name(name), age(age) {
        // 这里没有额外的初始化代码,因为它委托给带名字的构造函数
    }

    // 带年龄的构造函数,委托给带名字和年龄的构造函数
    Person(int age) : Person("Unknown", age) {}

private:
    std::string name;
    int age;
};

在这个案例中,Person 类有多个构造函数。Person(int age) 构造函数通过委托给 Person(const std::string& name, int age) 构造函数来初始化 nameage。这样,我们不需要在 Person(int age) 构造函数中重复初始化 name 的代码。

2.3 使用委托构造函数简化复杂的类设计

参考代码如下:

class Rectangle {
public:
    // 构造函数,接受长和宽
    Rectangle(double length, double width) : length_(length), width_(width) {}

    // 委托构造函数,使用面积初始化长和宽
    Rectangle(double area) : Rectangle(sqrt(area), sqrt(area)) {}

    // 委托构造函数,使用正方形的对角线长度初始化
    Rectangle(double diagonal) : Rectangle(diagonal / sqrt(2), diagonal / sqrt(2)) {}

private:
    double length_;
    double width_;
};

在这个案例中,Rectangle 类有多个构造函数。其中一个构造函数接受 double 类型的面积参数,它通过委托给接受长度和宽度参数的构造函数来初始化对象。另一个构造函数接受对角线长度参数,它通过计算正方形的一半对角线来初始化长度和宽度。

通过这些案例,我们可以看到委托构造函数如何帮助我们减少代码重复,并使得类的构造函数更加清晰和易于维护。这种机制特别适用于那些具有多个构造函数和复杂初始化逻辑的类。

相关推荐

  1. [C++11] 理解委托构造函数

    2024-04-06 07:18:01       14 阅读
  2. 深入理解C#委托:为什么及如何使用委托

    2024-04-06 07:18:01       16 阅读
  3. C++关于拷贝构造函数的一些理解

    2024-04-06 07:18:01       9 阅读
  4. C#语言入门】16. 委托详解

    2024-04-06 07:18:01       19 阅读
  5. C/C++函数指针、C#委托是什么?

    2024-04-06 07:18:01       8 阅读
  6. 深入理解 C# Unity 中的事件和委托

    2024-04-06 07:18:01       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-06 07:18:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-06 07:18:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-06 07:18:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-06 07:18:01       20 阅读

热门阅读

  1. VTK使用交互器来从三维体数据中提取二维切片

    2024-04-06 07:18:01       23 阅读
  2. VTK的交互器

    2024-04-06 07:18:01       18 阅读
  3. 【QT教程】QT6设计模式

    2024-04-06 07:18:01       22 阅读
  4. gbm模型做分类

    2024-04-06 07:18:01       14 阅读
  5. Acwing2024蓝桥杯日期问题

    2024-04-06 07:18:01       13 阅读