【C++】构造函数调用规则 ( 默认构造函数 | 默认无参构造函数 | 默认拷贝构造函数 | 构造函数调用规则说明 )

2023-10-15 17:06:39 浏览数 (1)

一、默认构造函数

C 类中 2 种特殊的构造函数 , 分别是 :

  • 默认无参构造函数 : 如果 C 类中 没有定义构造函数 , C 编译器会自动为该类提供一个 " 默认的无参构造函数 " , 函数体为空 , 不做任何操作 ;
  • 默认拷贝构造函数 : 如果 C 类中 没有定义拷贝构造函数 , C 编译器会自动为该类提供一个 " 默认的拷贝构造函数 " , 在函数中对成员变量进行简单的复制操作 ;

1、默认无参构造函数

如果 C 类中 没有定义构造函数 , C 编译器会自动为该类提供一个 " 默认的无参构造函数 " , 函数体为空 , 不做任何操作 ;

  • 没有定义构造函数 : 如果 没有为 C 类定义 构造函数 , C 编译器 将自动为该类 生成一个默认的无参构造函数 ;
  • 定义了构造函数 : 如果为 C 类 定义了其他类型的构造函数 ( 有参构造函数 / 无参构造函数 / 拷贝构造函数 ) , C 编译器 将不再自动生成默认的无参构造函数 ;

默认构造函数内容 : C 编译器 为类 定义的 默认无参构造函数 , 其函数体为空 , 如下代码所示 ;

代码语言:javascript复制
class MyClass {  
public:  
    int x;  
    // 默认构造函数  
    MyClass() {
    }  
};

下面的代码 , 会自动调用 默认的 无参构造函数 ;

代码语言:javascript复制
MyClass obj; // 调用 默认 构造函数

2、默认拷贝构造函数

" 默认拷贝构造函数 " 用于创建一个新对象作为现有对象的副本 , 其作用是将 现有对象 的成员变量 复制到 新对象中 ;

创建一个类对象 并将其 赋值给 另一个类对象时 , 会自动调用 默认拷贝构造函数 ;

如果 C 类中 没有定义拷贝构造函数 , C 编译器会自动为该类提供一个 " 默认的拷贝构造函数 " , 在函数中对成员变量进行简单的复制操作 ;

  • 没有定义拷贝构造函数 : 如果 没有为 C 类定义 拷贝构造函数 , C 编译器 将自动为该类 生成一个 默认的拷贝构造函数 ;
  • 定义了拷贝构造函数 : 如果为 C 类 定义了 拷贝构造函数 , C 编译器 将不再自动生成默认的拷贝构造函数 ;

默认拷贝构造函数内容 : C 编译器 为类 定义的 默认拷贝构造函数 , 在函数内部将 现有对象 的 成员变量 逐个赋值给 新对象 ;

代码语言:javascript复制
class MyClass {  
public:  
    int x;  
    // 默认拷贝构造函数  
    MyClass(const MyClass& other) {  
        x = other.x;  
    }  
};

下面的代码 , 第一行代码会自动调用默认的无参构造函数 , 第二行代码会自动调用默认的拷贝构造函数 ;

代码语言:javascript复制
MyClass obj; 			// 调用默认无参构造函数
MyClass obj2 = obj; 	// 调用默认拷贝构造函数

二、构造函数调用规则


1、构造函数规则说明

构造函数调用规则 :

  • 提供 默认无参构造函数 和 默认拷贝构造函数 : 如果 C 类中 没有定义 构造函数 时 , C 编译器 会提供 默认的 无参构造函数 和 默认的 拷贝构造函数 ;
  • 提供 默认拷贝构造函数 : 如果 C 类中 , 定义了 非拷贝构造函数 , 如 : 有参构造函数 / 无参构造函数 , C 编译器 不会提供 默认的无参构造函数 , 但是 会提供 默认的 拷贝构造函数 ;
    • 默认的 拷贝构造函数 只能进行 成员变量的 复制 ;
  • 特例 : 如果 C 类中 , 定义了 拷贝构造函数 , 那么 C 编译器不会提供 默认的无参构造函数 ;

2、代码示例 - 只定义拷贝构造函数

下面的代码中 , 定义了 拷贝构造函数 , C 编译器不会自动生成 默认的无参构造函数 和 默认的拷贝构造函数 ;

使用 Student s; 代码 创建对象 , 报错 “Student”: 没有合适的默认构造函数可用 ;

说明 C 编译器没有为该类生成 默认的无参构造函数 ;

代码示例 :

代码语言:javascript复制
#include "iostream"
using namespace std;

class Student
{
public:
	Student(const Student& s)
	{
		m_age = s.m_age;
		m_height = s.m_height;
		cout << "调用拷贝构造函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};


int main()
{
	// 定义了拷贝构造函数 不再生成默认无参构造函数
	Student s;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

代码语言:javascript复制
已启动生成…
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>hello_world.cpp
1>D:02_Project06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(23,10): error C2512: “Student”: 没有合适的默认构造函数可用
1>D:02_Project06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(4,7): message : 参见“Student”的声明
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

3、代码示例 - 只定义有参构造函数

下面的代码中 , 定义了 有参构造函数 , C 编译器不会自动生成 默认的无参构造函数 和 默认的拷贝构造函数 ;

使用 Student s; 代码 创建对象 , 报错 “Student”: 没有合适的默认构造函数可用 ;

说明 C 编译器没有为该类生成 默认的无参构造函数 ;

代码示例 :

代码语言:javascript复制
#include "iostream"
using namespace std;

class Student
{
public:
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "调用带参数构造函数 m_age = " << m_age << endl;
	}

	Student(const Student& s)
	{
		m_age = s.m_age;
		m_height = s.m_height;
		cout << "调用拷贝构造函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};


int main()
{
	// 定义了拷贝构造函数 不再生成默认无参构造函数
	Student s;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

代码语言:javascript复制
已启动生成…
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>hello_world.cpp
1>D:02_Project06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(31,10): error C2512: “Student”: 没有合适的默认构造函数可用
1>D:02_Project06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(4,7): message : 参见“Student”的声明
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

0 人点赞