我正在尝试制作一个袋子容器。当我超载=
运算符时,我所遇到的问题就出现了。
Zsak& Zsak::operator =(const Zsak& a)
{
(*this).V=a.V;
(*this).elemsz=a.elemsz;
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;
};
Zsak_Ba
将一个元素放入包中;
Zsak_Bol
从包中抽出一个元素;
我通过测试发现,const Zsak a
的地址标识为*this
的地址。
有了这个背景
Zsak z(5),c(5);
z.Zsak_Ba(1);
z.Zsak_Ba(1);
z.Zsak_Ba(1);
z.Zsak_Ba(2);
z.Zsak_Ba(2);
z.Zsak_Ba(2);
z.Zsak_Ba(4);
Zsak d=z;
d.Zsak_Bol(1);
cout<<z<<endl<<d;
打印:
1 2
2 3
4 1
1 2
2 3
4 1
它应该打印的是:
1 3
2 3
4 1
1 2
2 3
4 1
我应该怎样做才能获得这个? 我做错了什么?为什么?
非常感谢!
答案 0 :(得分:0)
您只复制指定运算符中的指针(而不是内容)。
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;
}
此外,我还没有看到elemsz
的更新位置(在成员初始化之外)。我想象它会在构造函数中。
Zsak(int meret)
{
V=new Elem[meret];
elemsz = meret;
}
和
Zsak ()
{
V=new Elem[100];
elemsz = 100;
}
值得注意的是,经常是#34; copy-swap&#34;用于实现赋值运算符,以及复制构造函数中的完整副本(基本上与您拥有它相反)。
&#34; copy-swap&#34;看起来像
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;
}
在为自己分配时会产生一些开销,如果需要,可以为此添加自我分配测试。
了解这是一项使用和实现动态内存的任务,最好将Elem
数组及其管理重新分解为主类之外的数据。通常更容易维护和纠正错误和问题。
答案 1 :(得分:0)
如果使用vector<Elem>
而不是手动动态内存,则不需要任何用户定义的复制构造函数或赋值运算符。它会起作用。这是首选的解决方案。让C ++为你完成工作。