【c++】构造函数
1.函数名称与类同名:构造函数名称必须与类名严格一致。
2.无返回值类型:无需声明返回类型(包括 void
)
3.构造函数一般为公有来对数据成员进行初始化(对象一般不能调用构造函数 但是可以使用定位new来调用构造函数–>将原空间的数据覆盖了–>如果原空间是在堆区->会造成内存泄漏)
构造函数的作用
- 1创建对象:构造函数在对象被实例化时自动调用,负责分配内存。
- 2初始化成员:通过初始化列表或函数体为对象的成员变量赋初始值。
- 3支持隐式类型转换:若构造函数只有一个参数(或其余参数有默认值),可隐式转换参数类型为类类型。
定义位置:
- 类内定义:直接在类体中实现(隐式内联inline)。
- 类外定义:在类内声明,类外实现(需通过
类名::
限定)。
class MyClass {
public:MyClass(); // 类内声明MyClass(int x, int y); // 重载构造函数
};MyClass::MyClass() { /* 类外定义 */ }
MyClass::MyClass(int x, int y) : a(x), b(y) { /* 初始化列表 */ }
能否重载:
-
支持重载:可定义多个参数列表不同的构造函数。
-
避免二义性:重载的构造函数需确保调用时参数能明确匹配某一版本。
class Point { public:Point(); // 默认构造Point(int x); // 单参数构造Point(int x, int y = 0); // 含默认参数(可能与 Point(int x) 冲突) };Point p1(5); // 错误!无法确定调用 Point(int) 还是 Point(int, int)
默认构造函数
-
系统自动生成:若未定义任何构造函数,编译器会生成一个无参的默认构造函数(不初始化成员变量)。
-
用户自定义后失效:若定义了任意构造函数(无论是否有参数),编译器不再生成默认构造函数。
class Demo { public:int val;// 未定义构造函数,编译器生成默认 Demo() {} };Demo d; // 合法,调用默认构造函数(val 未初始化)
默认参数与隐式类型转换
-
参数缺省值:可为构造函数参数设置默认值,但需遵循从右向左连续指定规则。
-
隐式转换条件:若构造函数仅有一个参数,或其余参数均有默认值,则可隐式转换参数类型为类类型。
class String { public:String(const char* str); // 单参数构造函数 };String s = "hello"; // 隐式调用 String(const char*)
-
禁止隐式转换:使用
explicit
关键字修饰构造函数–>必须通过显示类型强转
初始化列表
-
高效初始化:通过成员初始化列表直接初始化成员变量(避免先默认构造再赋值)。
-
必须使用的场景:
- 初始化
const
成员。 - 初始化引用成员。
- 初始化无默认构造函数的类类型成员。
class Student { private:const int id;std::string name; public:Student(int i, const std::string& n) : id(i), name(n) {} // 正确// Student(int i, const std::string& n) { id = i; name = n; } // 错误!id 是 const };
- 初始化