C ++期望一个浅拷贝,但不完全

时间:2012-07-06 08:18:36

标签: c++ class templates constructor

以下是Vector的模板类,它存储不同类型的数据元素。检查复制构造函数的代码并在main中。我期待的声明是“cout<<<<<<<<<<<<<< endl;”应该打印价值“费用”,因为复制承包商正在做一个浅的副本,但它是 印刷“责任”。

任何人都可以帮助我吗?感谢。

template<typename T>
class Vector{
  private:
      T* ptr;
      int size;
  public:
      Vector<T>(int s = 10){
           size = s;
           if(size!=0)
           {
               ptr = new T[size];

           }else{
               ptr = 0;
           }

      }
      Vector<T>(const Vector<T> &copy){
            this->size=copy.getSize();

            if(size !=0)
            {
                 ptr=new T[size];
                 for(int i=0;i<size;i++)
                    ptr[i] = copy.ptr[i];    
            }else{
               this->ptr=0;
            }
      }

      ~Vector<T>(){
         if(size>0)
         {
            delete[] ptr;
         }
      }
      int getSize() const
      {
          return size;    
      }
      const Vector<T> & operator = (const Vector<T> &rhs){
            if(this!=&rhs)
                 delete [] this->ptr;
                 size = rhs.size;
                 if(size!=0)
                 {
                      ptr=new T[size];
                      for(int i=0;i<size;i++)
                              ptr[i] = rhs.ptr[i];
            }

            return *this;

      }

      T& operator[](int index){
         if(index>=0 && index<=size)
            return ptr[index];
      }
};    




int main(int argc, char *argv[])
{
  Vector<char*> vCHAR(10);
  vCHAR[0]="asset";
  vCHAR[1]="income";
  vCHAR[2]="liability";

  Vector<char*> vCHAR2(vCHAR);
  vCHAR[2] = "expense";

  cout << vCHAR[2] << endl;

  cout << vCHAR2[2] << endl;

  system("PAUSE");
  return EXIT_SUCCESS;
}

4 个答案:

答案 0 :(得分:0)

copy ctor执行深层复制,因此vCHAR2有自己的元素数组。因此,当您更改源Vector的元素时,它不需要查看。 (当你改变你通过strcpy()指向的数据或访问vCHAR[2][0]='X';时会看到它(假如这不会让你的程序崩溃 - 当你对字符串文字进行操作时)。

答案 1 :(得分:0)

使用vCHAR [2] =&#34;费用&#34;您正在更改向量vCHAR内的指针,但vCHAR2 [2]仍然指向旧位置。简而言之 - 没有指针的浅表副本。如果你在复制矢量时从源头重新使用了T *,那么你就拥有了你想要的东西。

答案 2 :(得分:0)

您选择实施矢量的设计很危险。如果您决定使用一种节点分配方法来管理元素(而std::vector使用块分配方法),则必须小心指针和内存管理例程。您遇到的问题与使用指针的方式有关:在T* ptr;T& operator[]中,包括数组复制例程。在您的示例中,您正在使用指向char的指针 - char**(用char*替换模板)。如果您决定使用节点分配方法设计自己的向量实现,我建议至少使用它来实现struct VectorTraits并设计您的向量类。另外我建议使用std::string而不是char *。

答案 3 :(得分:0)

在行中:

Vector<char*> vCHAR2(vCHAR);

vCHAR2 [2]是指向字符串“liability”的指针。 这条线

vCHAR[2] = "expense";

不会改变vCHAR2 [2]的值,因为即使vCHAR [2]发生了变化,vCHAR2 [2]仍然指向“责任”。

要更改它,您只需直接分配即

vCHAR2[2] = "expense";

我认为你想要实现的目标是:

int* p = new int();
*p = 111;

int* q = p;

*p = 222; // change the content of what is pointed to

cout << *p << endl; // 222
cout << *q << endl; // 222 also

然而,这是一个不同的情况,因为我们正在改变指向的内容。 如果我们只进行指针赋值,则内容不变。只有指针被分配给另一个内存区域。

*p = 111;

int* q = p;

int z = 333;
p = &z; // do not change the content of what is pointed to, point to another area

cout << *p << endl; // 333
cout << *q << endl; // 222 still