2012-07-06 48 views
0

以下是存储不同类型数据元素的Vector的模板类。检查复制构造函数的代码并在main中。我当时期待的那样的陈述“cout < < vCHAR2 [2] < < endl;”应打印值“费用”,因为复印承包商正在做一个浅拷贝,但它打印“责任” 。C++预期为浅拷贝,但不完全为

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

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

请注意,您将字符串文字(例如'“asset”')分配到'char *'中。这是在惹麻烦。把那个'char *'作为'const'。 – eran 2012-07-06 08:31:15

+1

我强烈建议你使用'std :: string'而不是char指针。 – 2012-07-06 09:05:07

回答

0

复制ctor执行深度复制,因此vCHAR2具有自己的元素数组。因此,当您更改源矢量的元素时,不需要看到它。 (当你改变你通过strcpy()指向的数据或访问vCHAR[2][0]='X';(假设这不会导致你的程序崩溃 - 当你使用字符串文字)时,它会看到它)

+0

我得到了你......谢谢......但你能告诉我,为什么我的老师说这会导致char *的浅拷贝问题? – developer 2012-07-06 11:21:29

+0

@developer:它介于浅层和深层之间。你得到你自己的char * -array本身的版本,但不是指针指向的数据。所以修改这些数据会影响Vector的,但只是将其中一个指针重定向到另一个位置不会。 – 2012-07-06 11:30:05

+0

哦yessss ....非常感谢。 – developer 2012-07-06 12:31:34

0

with vCHAR [2] =“费用“,您正在更换矢量vCHAR内的指针,但vCHAR2 [2]仍指向旧位置。总之 - 没有指针的浅拷贝。如果您在复制矢量时从源头重新使用了T *,则可以获得所需的内容。

+0

感谢您的帮助......但不得不选择只有一个答案作为公认的答案.... – developer 2012-07-06 11:18:57

0

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

0

在行:

vCHAR2 [2]是一个指向字符串 “责任”。 线

vCHAR[2] = "expense"; 

不改变vCHAR2的值[2]因为vCHAR2 [2]仍然指向 “责任”,即使VCHAR [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 
+0

非常感谢你的解释。这也让我的头脑更清晰。 – developer 2012-07-06 11:17:57