我最近问了一个与这个问题有些相关的问题,但它的措辞非常糟糕,我不知道我在做什么。我有时间玩代码,希望这个问题更有意义。然而,事情仍然存在问题。我有一个B类。指向该类的指针(* p)。我只是想制作一个这个指针的副本(比如叫做q)。删除p但仍然有一个有效的指针指针指向p指向的相同信息。然后删除q。当我试图将它们设置为彼此相等时,我会遇到问题
class B
{
public:
B(); ~B();
B(const B &Overloading);
B& B::operator=(const B &Overloading);
vector<*A> stores_a; //class A contains ints, doubles etc. I filled this with
//pointers to class A
void Mr_Clean();
};
B::B() {}
~B::B()
{
Mr_Clean();
}
B::B(const B &Overloading)
{
for(size_t i=0; i<stores_a.size(); i++)
{
stores_A[i]=new A(*Overloading.stores_a[i]);
}
}
B::B& B::operator=(const B &Overloading)
{
if(this!=&Overloading)
{ Mr_Clean();
for(size_t i=0; i<stores_a.size(); i++)
{
stores_A[i]=new A(*Overloading.stores_a[i]);
}
}
return *this
}
void B::Mr_Clean()
{
for(size_t i=0; i<stores_A.size(); i++)
{
delete stores_A[i];
}
}
int main()
{
B *p=new B;
B *q=new B;
// fill some stuff. this is just random stuff I am making up
*q=*p; //compiles then Kaboom at this line
delete p;
delete q;
return 0;
}
我想我在赋值运算符上仍然存在一些概念上的差距。我已经阅读了很多教程,我觉得我正在做他们说的话......
另外一个问题,比如在这个例子中我也有一个成员int x在B.由于我调用了复制构造函数并重载了赋值运算符,我是否必须显式调用x = Overloading.x?我的意思是技术上我覆盖默认的复制构造函数没有?但是x只是一个普通的普通旧int。
答案 0 :(得分:1)
我在这里看到两个问题:
vector
的大小。但这不会导致任何错误因为 vector
的大小来循环搜索来源vector
的项目。这可能会导致运行时错误。您可以尝试使用此代码复制矢量:
stores_a.resize(Overloading.stores_a.size());
for(size_t i=0; i<Overloading.stores_a.size(); ++i)
{
stores_a[i]=new A(*Overloading.stores_a[i]);
}
或者这个(虽然上面的一般情况应该更快):
stores_a.clear();
for(size_t i=0; i<Overloading.stores_a.size(); ++i)
{
stores_a.push_back(new A(*Overloading.stores_a[i]));
}
答案 1 :(得分:0)
你在这里做的是你在赋值操作符中调用复制构造函数,它为对象分配内存。然后在复制构造函数的主体内部,再次为它们分配一些内存。这导致内存泄漏。 在赋值运算符内部,只需将一些数据插入到对象中,不要再次分配内存。 如果您特别需要Wikipedia
的帮助,请查看assignment operator或此处的链接