C++ 中的构造函数详解

构造函数(Constructor)是 C++ 类的一种特殊成员函数,在创建类对象时自动调用,用于初始化对象的成员变量。构造函数的名字与类名相同,没有返回值。


1. 构造函数的基本特点

  1. 名字与类名相同。
  2. 没有返回值(包括 void)。
  3. 在对象创建时自动调用。
  4. 可以被重载(通过不同的参数列表实现)。
  5. 如果没有显式定义构造函数,编译器会提供一个默认构造函数

2. 构造函数的类型

2.1 默认构造函数
  • 没有参数或所有参数都有默认值的构造函数。
  • 编译器会自动提供一个默认构造函数,如果没有定义其他构造函数。
#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() {  // 默认构造函数
        cout << "Default constructor called" << endl;
    }
};

int main() {
    MyClass obj; // 自动调用默认构造函数
    return 0;
}

输出:

Default constructor called

2.2 有参构造函数
  • 接受参数,用于根据传入的值初始化对象。
#include <iostream>
using namespace std;

class MyClass {
    int value;
public:
    MyClass(int val) {  // 有参构造函数
        value = val;
        cout << "Parameterized constructor called with value: " << value << endl;
    }
};

int main() {
    MyClass obj(10); // 自动调用有参构造函数
    return 0;
}

输出:

Parameterized constructor called with value: 10

2.3 拷贝构造函数
  • 用于根据已有对象创建新对象,完成对象的拷贝。
  • 如果没有定义,编译器会生成默认的拷贝构造函数(浅拷贝)。
#include <iostream>
using namespace std;

class MyClass {
    int value;
public:
    MyClass(int val) : value(val) {} // 有参构造函数

    // 拷贝构造函数
    MyClass(const MyClass& other) {
        value = other.value;
        cout << "Copy constructor called" << endl;
    }

    void display() {
        cout << "Value: " << value << endl;
    }
};

int main() {
    MyClass obj1(10);      // 调用有参构造函数
    MyClass obj2 = obj1;   // 调用拷贝构造函数

    obj2.display();
    return 0;
}

输出:

Copy constructor called
Value: 10

2.4 委托构造函数(C++11)
  • 一个构造函数调用另一个构造函数,减少重复代码。
#include <iostream>
using namespace std;

class MyClass {
    int value;
public:
    // 主构造函数
    MyClass(int val) : value(val) {}

    // 委托构造函数
    MyClass() : MyClass(0) {  // 调用 MyClass(int)
        cout << "Delegating constructor called" << endl;
    }

    void display() {
        cout << "Value: " << value << endl;
    }
};

int main() {
    MyClass obj;  // 调用委托构造函数
    obj.display(); 
    return 0;
}

输出:

Delegating constructor called
Value: 0

2.5 默认构造函数(C++11)
  • 使用 = default 明确要求编译器生成默认构造函数。
#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() = default; // 显式声明默认构造函数
};

int main() {
    MyClass obj;
    return 0;
}

2.6 禁用构造函数(C++11)
  • 使用 = delete 禁止特定的构造函数。
#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() = delete;  // 禁止默认构造函数
    MyClass(int val) {   // 允许有参构造函数
        cout << "Constructor with value: " << val << endl;
    }
};

int main() {
    // MyClass obj; // 错误,默认构造函数被删除
    MyClass obj(10); // 正常调用
    return 0;
}

3. 构造函数的调用顺序

  1. 单继承:基类的构造函数先执行,然后执行派生类的构造函数。
  2. 多继承:多个基类的构造函数按声明顺序执行,然后执行派生类的构造函数。
  3. 成员对象:成员对象的构造函数在外部类构造函数之前执行,按成员声明顺序调用。
示例:
#include <iostream>
using namespace std;

class Base {
public:
    Base() {
        cout << "Base constructor" << endl;
    }
};

class Member {
public:
    Member() {
        cout << "Member constructor" << endl;
    }
};

class Derived : public Base {
    Member m;
public:
    Derived() {
        cout << "Derived constructor" << endl;
    }
};

int main() {
    Derived obj;
    return 0;
}

输出:

Base constructor
Member constructor
Derived constructor

4. 初始化列表

初始化列表用于在构造函数中直接初始化类的成员变量,效率更高。

初始化列表的优点
  • 避免了默认构造和赋值的二次操作。
  • 对于 const 或引用类型的成员变量,初始化列表是唯一的方法。
示例:
#include <iostream>
using namespace std;

class MyClass {
    const int x;  // 常量成员
    int& ref;     // 引用成员
public:
    MyClass(int val, int& r) : x(val), ref(r) { // 初始化列表
        cout << "Constructor called" << endl;
    }

    void display() {
        cout << "x: " << x << ", ref: " << ref << endl;
    }
};

int main() {
    int num = 20;
    MyClass obj(10, num);  // 初始化常量和引用
    obj.display();
    return 0;
}

输出:

Constructor called
x: 10, ref: 20

5. 构造函数的重载

构造函数可以根据参数列表进行重载,以支持多种对象初始化方式。

#include <iostream>
using namespace std;

class MyClass {
    int x, y;
public:
    MyClass() : x(0), y(0) {}              // 默认构造函数
    MyClass(int a) : x(a), y(0) {}         // 单参数构造函数
    MyClass(int a, int b) : x(a), y(b) {}  // 双参数构造函数

    void display() {
        cout << "x: " << x << ", y: " << y << endl;
    }
};

int main() {
    MyClass obj1;
    MyClass obj2(10);
    MyClass obj3(10, 20);

    obj1.display();
    obj2.display();
    obj3.display();

    return 0;
}

输出:

x: 0, y: 0
x: 10, y: 0
x: 10, y: 20

6. 构造函数的注意事项

  1. 不能为构造函数指定返回类型(即使是 void)。
  2. 构造函数可以是 explicit,避免隐式类型转换。
  3. 避免递归调用构造函数,会导致栈溢出。

总结

构造函数的主要作用是:

  • 自动初始化对象。
  • 提供灵活的初始化方式(如有参构造、拷贝构造、委托构造)。
  • 支持成员对象、继承等复杂场景的初始化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值