C++ 在按引用、按值传递参数时丢失

C++ 在按引用、按值传递参数时丢失,c++,C++,我想做一个袋子容器。当我重载=运算符时,会出现超越我的问题 Zsak& Zsak::operator =(const Zsak& a) { (*this).V=a.V; (*this).elemsz=a.elemsz; return *this; } Zsak& Zsak::operator =(const Zsak& a) { if (this == &a) { // or std::addressof(a) return *t

我想做一个袋子容器。当我重载=运算符时,会出现超越我的问题

Zsak& Zsak::operator =(const Zsak& a)
{
  (*this).V=a.V;
  (*this).elemsz=a.elemsz;
  return *this;
}
Zsak& Zsak::operator =(const Zsak& a)
{
  if (this == &a) { // or std::addressof(a)
    return *this;
  }

  delete[] V;

  elemsz=a.elemsz;
  V=new Elem[elemsz];
  for (std::size_t i = 0; i < elemsz; ++i) {
    V[i] = a.V[i];
  }
  return *this;
}
使用此标题:

class Zsak
{
public:
    Zsak (){V=new Elem[100];}
    Zsak (const Zsak & a)
    {
        *this=a;
    }
    Zsak(int meret)
    {
        V=new Elem[meret];
    }
    ~Zsak(){delete[] V;}
    Zsak& operator -(const Zsak& b);
    Zsak& operator =(const Zsak& a);
    void Zsak_Ba(int e);
    void Zsak_Bol(int e);
    bool Uress();
    int E_Hany(int e) const;
    friend std::ostream& operator << (std::ostream& out,const Zsak& z);
private:
    Elem  *V;
    int elemsz=0;

};
它打印:

1 2
2 3
4 1

1 2
2 3
4 1
它真正应该打印的是:

1 3
2 3
4 1

1 2
2 3
4 1
我应该怎么做才能得到这个? 我做错了什么?为什么


非常感谢

只能复制指针,而不能复制赋值运算符中的内容

Zsak& Zsak::operator =(const Zsak& a)
{
  (*this).V=a.V;
  (*this).elemsz=a.elemsz;
  return *this;
}
Zsak& Zsak::operator =(const Zsak& a)
{
  if (this == &a) { // or std::addressof(a)
    return *this;
  }

  delete[] V;

  elemsz=a.elemsz;
  V=new Elem[elemsz];
  for (std::size_t i = 0; i < elemsz; ++i) {
    V[i] = a.V[i];
  }
  return *this;
}

还值得注意的是,通常使用拷贝交换来实现赋值运算符,而拷贝构造函数中的完整拷贝基本上与您拥有的完全拷贝相反

复制交换看起来像

Zsak (const Zsak & a) : elemsz(a.elemsz)
{
  V = new Elem[elemsz];
  for (int i = 0; i < elemsz; ++i) { // copy the contents
    V[i] = a.V[i];
  }
}

Zsak& Zsak::operator =(const Zsak& a)
{
  Zsak temp(a);
  std::swap(this->elemsz, temp.elemsz);
  std::swap(this->V, temp.V);
  return *this;
}
分配给self会带来一些开销,如果需要,可以为此添加一个self-assignment测试


理解这是一项使用和实现动态内存的任务,最好在主类之外重新考虑Elem数组及其管理。当出现错误和问题时,通常更容易维护和纠正它们。

如果使用矢量而不是手动动态内存,则不需要任何用户定义的复制构造函数或赋值运算符。它会起作用的。这是首选的解决方案。让C++为你做这项工作。

你只在这里复制一个指针:*这个。v=A.v;那么现在两个对象指向相同的数据。如何消除这个问题呢?将RHS对象指向的数组的所有元素分配给LHS对象指向的数组的元素。请原谅@juanchopanza,但你能给我举个例子吗?注意Zsak d=z;调用复制构造函数,而不是赋值运算符。@n解构调用时,所有V=new Elem[elemsz]都将被删除?我在这里设置了elemsz:private:Elem*V;int elemsz=0;这样做不好?@lero,是的,将在析构函数中调用delete[]。设置elemsz是一个好主意,但是当您在V中分配内存时需要更新它。非常感谢!我看了几个小时的代码…再次感谢!我知道这一点……但这是一项任务:我必须动态地完成它。
Zsak (const Zsak & a) : elemsz(a.elemsz)
{
  V = new Elem[elemsz];
  for (int i = 0; i < elemsz; ++i) { // copy the contents
    V[i] = a.V[i];
  }
}

Zsak& Zsak::operator =(const Zsak& a)
{
  Zsak temp(a);
  std::swap(this->elemsz, temp.elemsz);
  std::swap(this->V, temp.V);
  return *this;
}