三、面向对象
约 948 字大约 3 分钟
2026-04-28
C++构造函数有几种,分别什么作用?
- 默认构造函数
如果没有显式定义任何构造函数,编译器会自动生成一个默认构造函数。
如果定义了其他构造函数,编译器不会自动生成默认构造函数,除非显式声明 = default。
- 参数化构造函数
允许在创建对象时传入参数,直接初始化成员变量。
可以重载多个版本以适应不同的初始化需求。
- 拷贝构造函数
形式为ClassName(const ClassName& other),用于深拷贝或浅拷贝。
如果未定义,编译器会生成一个默认的拷贝构造函数(按成员浅拷贝)。
- 移动构造函数(C++11)
形式为 ClassName(ClassName&& other),用于“窃取”临时对象(右值)的资源,避免不必要的拷贝。
典型应用场景:STL容器、智能指针等需要高效资源管理的场景。
- 委托构造函数(C++11)
允许一个构造函数调用同类中的其他构造函数,避免代码重复。
示例:ClassName() : ClassName(0, 0) {}。
- 继承构造函数(C++11)
派生类通过using Base::Base直接继承基类的构造函数(C++11特性)。
注意:继承的构造函数不会初始化派生类新增的成员。
什么是构造函数和析构函数?构造函数和析构函数可以是虚函数吗?为什么?
构造函数是用于初始化对象的特殊成员函数,析构函数是对象销毁时自动调用,用于清理资源的特殊成员函数。
构造函数不能被声明为虚函数,构造期间虚表指针尚没有完全建立,而虚函数调用需要通过虚表,而构造期间这个机制不起作用。
析构函数可以声明为虚函数(特别是基类析构函数),确保通过基类指针删除派生类对象时调用正确的析构函数链,避免资源泄漏和未定义行为,如果不是虚函数,通过基类指针删除派生类对象会导致派生类部分未被正确销毁。
重载和重写,又追着问virtual 和 override的区别?
- 重载(Overload):函数名相同,参数不同,发生在同一个作用域(类内)。
即在同一个类里,函数名字一样,但参数不一样,编译器自己能分清。
- 重写(Override):派生类中重写父类的虚函数,函数名、参数、返回值完全相同,使用virtual 和 override 关键字。
virtual 是用在父类函数上,告诉编译器:“这个函数以后可能会被重写”,所以真正调用哪个版本,要在运行时决定。; override 是用在子类函数上,告诉编译器:“我就是要重写你父类的函数”。
C++怎么实现多态?
C++多态分为编译时多态和运行时多态:
编译时多态:通过函数重载和模板实现
运行时多态:通过虚函数和继承实现
虚函数表(vtable):每个包含虚函数的类都有一个虚函数表,存储虚函数地址
虚指针(vptr):每个对象包含一个指向其类虚函数表的指针
动态绑定:通过vptr在运行时确定调用哪个函数实现
