前言
这一篇文章是上一篇的续集(这里有上篇链接)前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数。也相信大家都掌握的不错,接下来博主将会带领大家继续学习有关C++比较重要的知识点——类和对象。下面话不多说坐稳扶好咱们要开车了。
一、类的6个默认成员函数
如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数
1. 默认构造函数(Default Constructor):如果类没有定义任何构造函数,编译器会自动生成一个默认构造函数。默认构造函数没有参数,用于创建一个对象时进行初始化操作。
2. 析构函数(Destructor):析构函数在对象被销毁时调用,用于释放对象所占用的资源,如释放动态分配的内存、关闭文件等。析构函数没有参数,且其名称以波浪线(~)开头,后跟类名。
3. 拷贝构造函数(Copy Constructor):拷贝构造函数用于将一个已经存在的对象的数据成员复制到另一个对象中。当使用一个对象初始化另一个对象、函数参数以值传递方式传递对象、或者以值返回对象时,拷贝构造函数会被自动调用。拷贝构造函数有一个参数,类型为同类对象的引用。
4. 拷贝赋值运算符(Copy Assignment Operator):拷贝赋值运算符用于将一个已经存在的对象的数据成员复制到另一个对象中。当使用赋值运算符=给一个已经初始化的对象赋值时,拷贝赋值运算符会被自动调用。拷贝赋值运算符有一个参数,类型为同类对象的引用,返回类型为引用。
5. 移动构造函数(Move Constructor):移动构造函数用于将一个临时对象或者将要被销毁的对象的资源(如动态分配的内存)“移动”给另一个对象,避免了不必要的数据拷贝。移动构造函数有一个参数,类型为同类对象的引用。
6. 移动赋值运算符(Move Assignment Operator):移动赋值运算符用于将一个临时对象或者将要被销毁的对象的资源(如动态分配的内存)“移动”给另一个对象,避免了不必要的数据拷贝。移动赋值运算符有一个参数,类型为同类对象的引用,返回类型为引用。
需要注意的是:如果自定义了析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数或移动赋值运算符中的任何一个,编译器将不再为该类生成相应的默认成员函数。
二、构造函数
⭕构造函数概念
C++中的构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数在对象被创建时自动被调用,主要目的是为对象的数据成员提供初始值,确保对象在创建后处于合适的状态。
⭕构造函数的特点
1. 构造函数的名称必须与类名完全相同,并且没有返回类型(连void也没有)。
2. 构造函数可以有参数,用于在创建对象时提供初始化值。这些参数可以有默认值,也可以是任意类型。
3. 构造函数可以被重载,也就是可以定义多个具有相同名称但参数列表不同的构造函数。这样可以根据不同的初始化需求选择合适的构造函数。
4. 在创建对象时,会自动调用与对象匹配的构造函数。也就是说,构造函数在对象被创建的时候自动被调用,无需手动调用。
5. 构造函数可以执行一些必要的初始化操作,如动态分配内存、打开文件、初始化数据成员等。
⭕常见构造函数的几种类型
1. 默认构造函数(Default Constructor)
没有参数的构造函数,用于创建对象时提供默认的初始值。
2. 带参构造函数(Parameterized Constructor)
带有参数的构造函数,用于根据提供的参数初始化对象的数据成员。
3. 复制构造函数(Copy Constructor)
以一个同类对象作为参数,用于根据已有对象创建新的对象。
4. 移动构造函数(Move Constructor)
以一个临时对象或将要被销毁的对象作为参数,用于“移动”资源(如动态分配的内存)而不是执行数据拷贝。
5. 类型转换构造函数(Conversion Constructor)
以其他类型的对象作为参数,用于将其他类型的对象转换为该类的对象。
构造函数在类的定义中是以公有(public)访问权限声明的,因为它们需要被外部代码调用来创建对象。一个类可以有多个构造函数,并且可以选择性地定义它们,如果没有定义任何构造函数,编译器会自动生成一个默认构造函数。
下面是一个简单的示例,展示了一个类 ‘ Person ’ 的构造函数的定义和使用:
#include <iostream> #include <string> class Person { public: // 默认构造函数 Person() { name = "Unknown"; age = 0; } // 带参构造函数 Person(const std::string& n, int a) { name = n; age = a; } // 打印信息的成员函数 void printInfo() { std::cout << "Name: " << name << ", Age: " << age << std::endl; } private: std::string name; int age; }; int main() { // 使用默认构造函数创建对象 Person p1; p1.printInfo(); // 输出:Name: Unknown, Age: 0 // 使用带参构造函数创建对象 Person p2("John", 25); p2.printInfo(); // 输出:Name: John, Age: 25 return 0; }
在上面的示例中,Person 类包含了一个默认构造函数和一个带参构造函数。通过这两个构造函数,可以选择使用不同的方式创建 Person 对象,从而灵活地满足不同的需求。