C++中默认构造函数被意外调用的原因咨询
为什么传入Location对象到Salesman构造函数时默认构造函数会被调用?
嘿,我来帮你捋捋这个问题——你遇到的默认构造函数被莫名调用的情况,大概率是Salesman类的成员初始化逻辑或者vector的隐式操作导致的,咱们一步步拆解:
最常见的原因:Salesman类的Location成员没在初始化列表显式初始化
假设你的Salesman类定义是类似这样的:
class Salesman { private: Location loc; // 包含一个Location类型的成员变量 public: // 构造函数只处理了传入的参数,没管loc的初始化 Salesman(Location l) { // 这里的代码执行前,编译器已经完成了成员变量的初始化 } };
C++的类构造规则是:进入构造函数体之前,所有成员变量必须完成初始化。如果你的loc没有在构造函数的初始化列表里被显式初始化,编译器会自动调用Location的默认构造函数来初始化它,之后才会执行构造函数体里的代码。
解决方法:把成员变量放到初始化列表里
修改Salesman的构造函数,用初始化列表显式初始化loc,这样就会调用拷贝构造函数而不是默认构造:
// 甚至可以把参数改成const引用,减少一次不必要的拷贝 Salesman(const Location& l) : loc(l) { // 现在loc会通过拷贝构造初始化,不会触发默认构造 }
另一种可能:vector的隐式初始化操作
你main函数里提到了std::vector...,如果vector做了这些操作,也会触发默认构造:
- 创建指定大小的vector:比如
std::vector<Salesman> salesmen(3);,会默认构造3个Salesman对象,每个Salesman里的Location成员也会默认构造 - vector扩容时,如果没有自定义分配器,新的元素会被默认构造(C++11之后部分场景会用移动构造,但默认初始化元素仍会调用默认构造)
举个完整的测试例子对比
错误写法(会触发默认构造)
#include <iostream> using namespace std; class Location { public: Location() { cout << "Location默认构造被调用\n"; } Location(int x, int y) { cout << "Location非默认构造被调用\n"; } Location(const Location& other) { cout << "Location拷贝构造被调用\n"; } }; class Salesman { private: Location loc; public: Salesman(Location l) { // 进入这里前,loc已经被默认构造了 } }; int main() { Location a(1,1); // 输出:Location非默认构造被调用 Salesman s(a); // 先输出:Location默认构造被调用,再输出:Location拷贝构造被调用(参数值传递) return 0; }
修正写法(不会触发默认构造)
class Salesman { private: Location loc; public: Salesman(const Location& l) : loc(l) { // 输出:Location拷贝构造被调用(参数是引用,无额外拷贝) } };
内容的提问来源于stack exchange,提问作者agneau
相关产品推荐
相关产品推荐

