Bootstrap

全面理解-c++中的各种构造函数

在 C++ 中,构造函数是用于初始化对象的特殊成员函数。根据其用途和特性,构造函数可以分为以下几种类型:


1. 默认构造函数(Default Constructor)

  • 作用:无参数或所有参数都有默认值,用于创建对象时不提供显式初始化值。

  • 触发场景

    • 对象声明时不提供参数。

    • 数组或容器中未显式初始化的元素。

  • 示例

    class MyClass {
    public:
        MyClass() { // 默认构造函数
            std::cout << "Default Constructor\n";
        }
    };
    
    MyClass obj; // 调用默认构造函数
     

2. 参数化构造函数(Parameterized Constructor)

  • 作用:接受一个或多个参数,用于根据传入的值初始化对象。

  • 示例

    class MyClass {
    public:
        MyClass(int x, int y) { // 参数化构造函数
            std::cout << "Parameterized Constructor\n";
        }
    };
    
    MyClass obj(10, 20); // 调用参数化构造函数
     

3. 拷贝构造函数(Copy Constructor)

  • 作用:用同类型的另一个对象初始化新对象,通常用于深拷贝。

  • 触发场景

    • 对象按值传递。

    • 对象按值返回。

    • 显式拷贝对象。

  • 示例

    class MyClass {
    public:
        MyClass(const MyClass& other) { // 拷贝构造函数
            std::cout << "Copy Constructor\n";
        }
    };
    
    MyClass obj1;
    MyClass obj2 = obj1; // 调用拷贝构造函数


4. 移动构造函数(Move Constructor)

  • 作用:用同类型的另一个对象的资源初始化新对象,通常用于高效转移资源。

  • 触发场景

    • 对象通过 std::move 转移。

    • 函数返回临时对象(若未优化)。

  • 示例

    class MyClass {
    public:
        MyClass(MyClass&& other) noexcept { // 移动构造函数
            std::cout << "Move Constructor\n";
        }
    };
    
    MyClass obj1;
    MyClass obj2 = std::move(obj1); // 调用移动构造函数


5. 委托构造函数(Delegating Constructor)

  • 作用:一个构造函数调用同类中的另一个构造函数,避免代码重复。

  • 示例

    class MyClass {
    public:
        MyClass() : MyClass(0) { // 委托构造函数
            std::cout << "Delegating Constructor\n";
        }
        MyClass(int x) { // 目标构造函数
            std::cout << "Target Constructor\n";
        }
    };
    
    MyClass obj; // 先调用目标构造函数,再调用委托构造函数


6. 转换构造函数(Converting Constructor)

  • 作用:接受一个参数,用于隐式或显式地将其他类型转换为当前类类型。

  • 示例

    class MyClass {
    public:
        MyClass(int x) { // 转换构造函数
            std::cout << "Converting Constructor\n";
        }
    };
    
    MyClass obj = 10; // 隐式调用转换构造函数


7. 显式构造函数(Explicit Constructor)

  • 作用:防止隐式类型转换,避免意外的构造函数调用。

  • 示例

    class MyClass {
    public:
        explicit MyClass(int x) { // 显式构造函数
            std::cout << "Explicit Constructor\n";
        }
    };
    
    MyClass obj1(10); // 合法
    MyClass obj2 = 10; // ❌ 错误:禁止隐式转换
     

8. 继承中的构造函数

  • 基类构造函数调用:派生类构造函数可显式调用基类构造函数。

  • 示例

    class Base {
    public:
        Base(int x) {
            std::cout << "Base Constructor\n";
        }
    };
    
    class Derived : public Base {
    public:
        Derived(int x) : Base(x) { // 调用基类构造函数
            std::cout << "Derived Constructor\n";
        }
    };
    
    Derived obj(10);
     

9. 默认成员初始化与构造函数

  • 默认成员初始化:在类定义中直接初始化成员变量。

  • 示例

    class MyClass {
    private:
        int x = 10; // 默认成员初始化
    public:
        MyClass() {
            std::cout << "Default Constructor\n";
        }
    };
     

总结

构造函数类型作用描述示例场景
默认构造函数无参数初始化对象MyClass obj;
参数化构造函数根据参数初始化对象MyClass obj(10);
拷贝构造函数用另一个对象初始化新对象MyClass obj2 = obj1;
移动构造函数转移另一个对象的资源MyClass obj2 = std::move(obj1);
委托构造函数调用同类中的其他构造函数MyClass() : MyClass(0) {}
转换构造函数将其他类型转换为当前类类型MyClass obj = 10;
显式构造函数禁止隐式类型转换explicit MyClass(int x);
继承中的构造函数派生类调用基类构造函数Derived(int x) : Base(x) {}
默认成员初始化在类定义中直接初始化成员变量int x = 10;

最佳实践

  • 为资源管理类实现 拷贝构造函数 和 移动构造函数

  • 使用 显式构造函数 避免隐式转换。

  • 利用 委托构造函数 减少代码重复。

  • 在继承中显式调用基类构造函数。

;