类的构造函数
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
下面的实例有助于更好地理解构造函数的概念:
实例
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created
Length of line : 6
带参数的构造函数
默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:
实例
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(double len); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line(10.0);
// 获取默认设置的长度
cout << "Length of line : " << line.getLength() <<endl;
// 再次设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created, length = 10
Length of line : 10
Length of line : 6
使用初始化列表来初始化字段
使用初始化列表来初始化字段:
Line::Line( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}
上面的语法等同于如下语法:
Line::Line( double len)
{
length = len;
cout << "Object is being created, length = " << len << endl;
}
假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:
C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
....
}
类的析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
下面的实例有助于更好地理解析构函数的概念:
实例
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数声明
~Line(); // 这是析构函数声明
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created
Length of line : 6
Object is being deleted
为什么C++的构造函数在class new 的就自动执行呢?
在C++中,构造函数在对象创建时自动执行的设计是语言的核心特性,其背后蕴含着深刻的工程哲学和系统设计思想。以下是结构化解析:
内存分配与构造分离
new操作符实际执行两个独立操作:
MyClass* obj = new MyClass();
// 等价于:
void* mem = operator new(sizeof(MyClass)); // 1. 仅分配原始内存
MyClass* obj = new(mem) MyClass(); // 2. 在内存地址调用构造函数构造函数的本质
编译器将构造函数视为类型初始化器:
编译期在所有对象创建点自动插入构造函数调用
构造函数签名经特殊处理(如添加隐式this指针参数)
设计哲学解析
一、对象生命周期完整性保障
阶段 自动行为 意义
创建期 构造自动执行 确保对象从诞生起就处于有效状态
生存期 方法手动调用 赋予开发者控制权
销毁期 析构自动执行 防止资源泄漏(RAII核心)
二、类型系统安全的基石
class Database {
public:
Database() { connect("default_server"); } // 强制初始化
};
// 若不自动构造:
Database* db = (Database*)malloc(sizeof(Database));
db->query("SELECT..."); // 崩溃!未初始化的连接三、面向对象范式的实现基础
继承链构造:自动按顺序调用基类构造函数
class Base { Base() {/*基类初始化*/} };
class Derived : public Base {
Derived() : Base() {/*编译器自动插入基类构造*/}
};成员初始化:按声明顺序自动构造成员对象
💡 关键优势分析
防御性编程强化
class File { HANDLE hFile; public: File(const char* name) : hFile(OpenFile(name)) { if(!hFile) throw "打开失败"; // 创建即验证 } }; // 使用时无法绕过验证 File log("data.bin"); // 要么有效对象,要么异常设计权衡与边界
- 与C语言的本质区别

🌟 总结:自动构造的核心价值
安全屏障:消除未初始化对象风险
范式实现:支撑RAII/异常安全等核心特性
系统契约:对象诞生即满足类不变式(class invariant)
工程效率:减少样板代码(对比C的手动初始化)
类型完备:实现真正意义上的抽象数据类型(ADT)
正如C++之父Bjarne Stroustrup所言:
“构造函数不是可选的——它们定义了对象存在的意义”。
这种设计强制保证了对象语义完整性,是C++类型安全的基石。
怎么判断储C++的class 内部的function哪一个是构造函数,哪一个是析构函数
在C++中,构造函数和析构函数有明确的语法特征和功能定位。以下是简明清晰的判断指南:
🔍 构造函数识别特征
命名规则
函数名 必须与类名完全相同(大小写敏感)
class MyClass {
public:
MyClass(); // ✅ 构造函数
};无返回类型
不声明任何返回类型(连 void 都不需要)
class Student {
public:
Student(string name); // ✅ 构造(无返回类型)
void setGrade(); // ❌ 普通方法(有void)
};可重载特性
一个类可以有 多个构造函数(参数列表不同)
class Point {
public:
Point(); // ✅ 默认构造
Point(int x, int y); // ✅ 带参构造
};析构函数识别特征
命名规则
函数名 必须是 ~类名(波浪号前缀)
class Database {
public:
~Database(); // ✅ 析构函数
};无参数无返回值
严格无参数,且不声明返回类型
class FileHandler {
public:
~FileHandler(); // ✅ 正确形式
~FileHandler(int); // ❌ 错误(不可带参数)
};唯一性
每个类 有且仅有一个 析构函数(不可重载)
遇到类成员函数时问:
是否与类名同名? → 构造函数候选
是否带波浪号前缀? → 析构函数候选
是否有返回类型? → 普通方法(非构造/析构)
析构函数带参数? → 语法错误(必须无参)
掌握这些规则后,您能瞬间识别任何C++类中的构造/析构函数。这种设计确保对象 诞生即初始化(构造),消亡即清理(析构),是C++资源管理的基石 💪。
特殊场景辨析
默认构造
无参数的构造函数(编译器自动生成若未定义)
class Widget {
public:
Widget(); // 显式默认构造
// 若未声明,编译器生成隐式默认构造虚析构函数(多态基类必备)
class Shape {
public:
virtual ~Shape(); // ✅ 虚析构(允许派生类正确释放)
};.
评论 (0)