我正在编写一个简单的nD-vector类,但遇到了一个奇怪的错误。我已经把课程剥离到最低限度,仍然可以重现这个错误:
#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???
从表面上看,这似乎工作正常,两个测试都打印出正确的值。然而,在主程结束时程序崩溃了一个段错误,我已经追溯到nvector的析构函数。
起初我认为(不正确的)默认赋值运算符是以某种方式被调用的,这就是我添加(当前)未实现的显式赋值运算符来排除这种可能性的原因。
所以我的复制构造函数必须是错误的,但我正处于那些我盯着极其简单的代码并且看不到它的日子之一。你们有什么想法吗?
答案 0 :(得分:10)
转换构造函数的模板化实现从不被视为复制构造函数的候选函数。永远不会调用模板化的复制构造函数。相反,编译器使用隐式生成的“默认”复制构造函数实现,该实现执行浅复制,具有明显的后果。
换句话说,您在上面实现的模板化构造函数永远不会用作复制构造函数,只能用作转换构造函数。您必须将复制构造函数显式实现为非模板函数。