一、默认构造函数
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_Project 06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(23,10): error C2512: “Student”: 没有合适的默认构造函数可用
1>D: 02_Project 06_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_Project 06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(31,10): error C2512: “Student”: 没有合适的默认构造函数可用
1>D: 02_Project 06_Visual_StudioHelloWorldHelloWorldhello_world.cpp(4,7): message : 参见“Student”的声明
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========