C++默认构造函数详解

 更新时间:2026年06月05日 08:50:55   作者:Yolo_TvT  
本文详细解析了C++中默认成员函数的概念,包括默认构造函数的作用与生成规则,并探讨了何时需要自定义默认构造函数及其应用场景,感兴趣的朋友一起看看吧

一、类的默认成员函数

  • 当你定义一个空类时,编译器并不会真的“空手而归”。它会自动为你生成6个(C++98)或更多(C++11后)特殊的成员函数。这些函数被称为默认成员函数。
  • 他们分别是:
函数作用
默认构造函数初始化对象
析构函数清理对象资源
拷贝构造函数用已有对象初始化新对象
赋值运算符重载将已有对象赋值给另一对象
移动构造函数(C++11)用临时对象“转移”资源
移动赋值运算符(C++11)临时对象赋值
  • 如果没有主动声明这些函数,编译器就会自动生成一个默认版本,即为默认成员函数。

二、构造函数的基本概念

  • 构造函数是类中一种特殊的成员函数,它在对象创建时自动调用,用于初始化对象的成员变量。

构造函数的规则:

  • 函数名与类名完全相同
  • 没有返回值
  • 可以重载(可以有多个参数不同的构造函数)
  • 对象创建时自动执行

三、默认构造函数的含义

  • 默认构造函数是指可以无实参可调用的构造函数。它包括两种情况:
    • 程序员定义的默认构造函数:
      • 程序员定义的无参构造函数。
      • 程序员定义的全缺省参数的构造函数。
    • 程序员没有定义构造函数,编译器自动生成的隐式默认构造函数。
class Student {
public:
    // 无参构造函数
    Student() {
        name = "无名";
        age = 0;
    }
private:
    string name;
    int age;
};
cpp
class Point {
public:
    // 全缺省参数的构造函数(也是默认构造函数)
    Point(int x = 0, int y = 0) : x(x), y(y) {}
private:
    int x, y;
};

四、编译器自动生成的默认构造函数

  • 若程序员没有实现构造函数,编译器会为你生成一个隐式默认构造函数。
class Dog {
    string name;
    int age;
    // 编译器自动生成 Dog() {}
};

这个隐式构造函数会做什么?

  • 对于内置类型(int, char, 指针等):不做任何初始化(不同编译器效果不同)。
  • 对于自定义类型成员:调用它们各自的默认构造函数。
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A的构造函数" << endl; }
};
class B {
    int x;      // 内置类型,不会初始化(垃圾值)
    A a;        // 类类型,会调用A的默认构造函数
};
int main() {
    B b;   // 输出:A的构造函数(x保持随机)
}

一旦你实现了构造函数,编译器就不再生成默认构造函数

class Student {
public:
    Student(string n) { name = n; }  // 自定义构造函数
private:
    string name;
};
int main() {
    Student s1("张三");  // 正确
    // Student s2;       // 错误!没有默认构造函数可用
}

如果你既需要带参构造,又需要无参构造,需要手动提供默认构造函数。

五、默认构造函数的用途

1. 定义对象而不初始化

class Array {
    int* data;
public:
    Array() { data = nullptr; }  // 允许定义空数组对象
};
Array arr;   // 调用默认构造

2. 作为容器元素的默认构造要求

STL容器(如vector)在扩容或创建元素时,经常需要元素的默认构造函数。

vector<Student> v(10);  // 需要Student有默认构造函数

3. 继承体系中基类的初始化

派生类构造函数会自动调用基类的默认构造函数(如果基类没有默认构造,派生类必须显式调用基类的带参构造)。

六、什么时候需要自定义默认构造函数?

情况是否需要
类没有指针成员,且成员都有合理的默认值不需要,编译器生成即可
成员中需要分配资源需要(在构造中分配并初始化)
需要给成员变量设置特定的初始值需要
类有自定义的带参构造,但仍需无参创建对象需要
class MyString {
    char* buf;
public:
    // 自定义默认构造:给指针一个安全的初始值
    MyString() {
        buf = new char[1];
        buf[0] = '\0';
    }
};

七、C++11 的改进:default 和 delete

C++11允许你显式要求编译器生成默认版本,或禁止某个构造函数。

class Widget {
public:
    Widget() = default;           // 手动要求编译器生成默认构造
    Widget(const Widget&) = delete; // 禁止拷贝构造
};

八、一个完整的例子

#include <iostream>
#include <string>
using namespace std;
class Book {
public:
    // 默认构造函数
    Book() {
        title = "未命名";
        price = 0.0;
        cout << "调用默认构造函数" << endl;
    }
    // 带参构造函数(不是默认构造)
    Book(string t, double p) : title(t), price(p) {
        cout << "调用带参构造函数" << endl;
    }
    void print() {
        cout << "书名:" << title << ",价格:" << price << endl;
    }
private:
    string title;
    double price;
};
int main() {
    Book b1;              // 调用默认构造
    Book b2("C++教程", 59.9); // 调用带参构造
    b1.print();
    b2.print();
    return 0;
}
输出:
text
调用默认构造函数
调用带参构造函数
书名:未命名,价格:0
书名:C++教程,价格:59.9

到此这篇关于C++:默认构造函数的文章就介绍到这了,更多相关C++:默认构造函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c++中try catch的用法小结

    c++中try catch的用法小结

    这篇文章主要介绍了c++中try catch的用法小结,需要的朋友可以参考下
    2018-01-01
  • 基于C语言编写一个简单的Web服务器

    基于C语言编写一个简单的Web服务器

    C语言可以干大事,这篇文章主要为大家详细介绍了如何基于C语言可以完成一个简易的Web服务器,希望这篇文章会帮你你对C语言有更深入的理解
    2024-03-03
  • 详细了解C语言二叉树的建立与遍历

    详细了解C语言二叉树的建立与遍历

    这篇文章主要介绍了C中二叉树的建立和各种遍历实例代码,涉及树节点的定义,后序遍历,层序遍历,深度优先和广度优先等相关内容,具有一定借鉴价值,需要的朋友可以参考下
    2021-07-07
  • C++中使用正则匹配问题

    C++中使用正则匹配问题

    这篇文章主要介绍了C++中使用正则匹配问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言实现简单五子棋小游戏

    C语言实现简单五子棋小游戏

    这篇文章主要为大家详细介绍了C语言实现简单五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • QT利用QPdfWriter实现绘制PDF(支持表单输出)

    QT利用QPdfWriter实现绘制PDF(支持表单输出)

    这篇文章主要为大家详细介绍了QT如何利用QPdfWriter实现绘制PDF,并可以支持表单输出。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01
  • C++ Cartographer源码中关于MapBuilder的声明与构造

    C++ Cartographer源码中关于MapBuilder的声明与构造

    这篇文章主要介绍了C++ Cartographer源码中关于MapBuilder的声明与构造,前面已经谈到了Cartographer中添加轨迹的方法和传感器的数据流动走向。在添加轨迹的时候,除了添加位姿估计器还有采样器,订阅回调函数之外,最重要的是通过map_builder_bridge添加了一条轨迹
    2023-03-03
  • 用C语言实现单链表的各种操作(二)

    用C语言实现单链表的各种操作(二)

    本篇文章是对用C语言实现单链表的各种操作进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++ 读写文件安全又简洁的简单实例

    C++ 读写文件安全又简洁的简单实例

    这篇文章主要介绍了C++ 读写文件安全又简洁的简单实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • 使用C语言实现字符串左旋和右旋问题

    使用C语言实现字符串左旋和右旋问题

    这篇文章主要介绍了使用C语言实现字符串左旋和右旋问题,需要的朋友可以参考下
    2018-07-07

最新评论