为何C++在用户定义模板构造函数后仍使用默认拷贝构造函数?
为什么模板构造函数不会替代默认拷贝构造函数?
嘿,这个问题其实涉及到C++标准对拷贝构造函数的明确规定,我来给你掰扯清楚:
首先,先明确一个核心规则:模板构造函数永远不会被当作拷贝构造函数或者移动构造函数。哪怕某个模板实例化后的签名看起来和拷贝构造函数一模一样,编译器也不会把它当成真正的拷贝构造函数。
回到你的代码里,你的jp模板类定义了两个构造函数:
- 无参构造函数
jp<T>() - 一个接受
T类型参数的构造函数jp<T>(T a)
但你没有显式定义针对jp<T>自身类型的拷贝构造函数——也就是签名类似jp(const jp&)或者jp(jp&)的非模板构造函数。这时候编译器就会自动为你生成一个默认拷贝构造函数。
当你执行拷贝操作(比如jp<A> x; jp<A> y = x;)时,编译器会优先匹配那个默认生成的拷贝构造函数,而不会去实例化你的模板构造函数。因为模板构造函数本质上是用来处理其他类型的构造场景,而非自身类的拷贝。
那如果想要自定义拷贝行为怎么办?你必须显式地写出针对jp<T>的拷贝构造函数,比如:
template <class T> class jp { public: T* ptr; jp<T>() { ptr = 0; } jp<T>(T a) { std::cerr << "Recording address...\n"; ptr = new T(a); } // 显式定义拷贝构造函数 jp(const jp& other) { std::cerr << "Custom copy constructor\n"; ptr = new T(*other.ptr); } };
这样编译器才会使用你自定义的拷贝逻辑,而不是默认生成的版本。
总结一下:模板构造函数是通用构造逻辑的补充,而拷贝构造函数属于类的特殊成员函数,有严格的签名要求——必须是针对自身类类型的非模板函数,这是C++标准为了保证默认拷贝行为的稳定性和可预测性而做出的规定。
内容的提问来源于stack exchange,提问作者user2444353
相关产品推荐
相关产品推荐

