我正在编写一个简单的nD-vector类,但遇到了一个奇怪的bug.我已经将课程剥离到最低限度,仍然可以重现该错误:
#include <iostream>
using namespace std;
template<unsigned int size> class nvector
{
public:
nvector() {data_ = new double[size];}
~nvector() {delete[] data_;}
template<unsigned int size2>
nvector(const nvector<size2> &other)
{
data_ = new double[size];
int i=0;
for(; i<size && i < size2; i++)
data_[i] = other[i];
for(; i<size; i++)
data_[i] = 0;
}
double &operator[](int i) {return data_[i];}
const double&operator[](int i) const {return data_[i];}
private:
const nvector<size> &operator=(const nvector<size> &other); //Intentionally unimplemented for now
double *data_;
};
int main()
{
nvector<2> vector2d;
vector2d[0] = 1;
vector2d[1] = 2;
nvector<3> vector3d(vector2d);
for(int i=0; i<3; i++)
cout << vector3d[i] << " ";
cout << endl; //Prints 1 2 0
nvector<3> other3d(vector3d);
for(int i=0; i<3; i++)
cout << other3d[i] << " ";
cout << endl; //Prints 1 2 0
} //Segfault???
Run Code Online (Sandbox Code Playgroud)
从表面上看,这似乎工作正常,两个测试都打印出正确的值.然而,在主程结束时,程序崩溃了一个段错误,我已经追溯到nvector的析构函数.
起初我认为(不正确的)默认赋值运算符以某种方式被调用,这就是为什么我添加了(当前)未实现的显式赋值运算符来排除这种可能性.
所以我的复制构造函数必须是错误的,但我有一天,我正在盯着非常简单的代码,只是看不到它.你们有什么想法吗?
AnT*_*AnT 10
转换构造函数的模板化实现从不被视为复制构造函数的候选函数.永远不会调用模板化的复制构造函数.相反,编译器使用隐式生成的"默认"复制构造函数实现,该实现执行浅复制,具有明显的后果.
换句话说,您在上面实现的模板化构造函数永远不会用作复制构造函数,只能用作转换构造函数.您必须将复制构造函数显式实现为非模板函数.