复制构造函数bug

时间:2010-05-27 19:14:28

标签: c++

我正在编写一个简单的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的析构函数。

起初我认为(不正确的)默认赋值运算符是以某种方式被调用的,这就是我添加(当前)未实现的显式赋值运算符来排除这种可能性的原因。

所以我的复制构造函数必须是错误的,但我正处于那些我盯着极其简单的代码并且看不到它的日子之一。你们有什么想法吗?

1 个答案:

答案 0 :(得分:10)

转换构造函数的模板化实现从不被视为复制构造函数的候选函数。永远不会调用模板化的复制构造函数。相反,编译器使用隐式生成的“默认”复制构造函数实现,该实现执行浅复制,具有明显的后果。

换句话说,您在上面实现的模板化构造函数永远不会用作复制构造函数,只能用作转换构造函数。您必须将复制构造函数显式实现为非模板函数。