【问题标题】:C++ expected a shallow copy but not exactlyC++ 期望一个浅拷贝,但不完全是
【发布时间】:2012-07-06 08:18:35
【问题描述】:

下面是Vector的一个模板类,它存储了不同类型的数据元素。检查复制构造函数的代码和主代码。我所期望的语句“cout

有人可以帮我吗?谢谢。

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;
}

【问题讨论】:

  • 请注意,您将字符串文字(例如"asset")分配给char*。那是自找麻烦。将 char* 设为 const
  • 我强烈建议您使用std::string 而不是字符指针。

标签: c++ class templates constructor


【解决方案1】:

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

【讨论】:

  • 我知道了......谢谢......但你能告诉我为什么我的老师说它会导致 char* 出现浅拷贝问题吗?
  • @developer:它介于浅拷贝和深拷贝之间。你得到你自己版本的 char*-array 本身,但不是指针所指的数据。所以修改这个数据会影响两个 Vector,但只是将其中一个指针重定向到另一个位置不会。
【解决方案2】:

使用 vCHAR[2] = "expense" 您正在更改向量 vCHAR 内的指针,但 vCHAR2[2] 仍指向旧位置。简而言之 - 没有指针的浅拷贝。如果您在复制向量时重新使用了源中的 T*,那么您将得到您想要的。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      行内:

      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
      

      【讨论】:

      • 非常感谢您的解释。这也让我的思路更加清晰。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 2016-09-27
      • 2013-03-09
      • 2012-04-12
      • 2015-08-23
      相关资源
      最近更新 更多