我在这里引起内存泄漏还是可以这样做?我应该使用智能指针成员而不是参考吗?可以使用动态分配的内存初始化引用成员吗?
class A
{
public:
A() : b_(*(new B))
{}
private:
B& b_;
};
int main()
{
A a;
return 0;
}
我在这里引起内存泄漏还是可以这样做?我应该使用智能指针成员而不是参考吗?可以使用动态分配的内存初始化引用成员吗?
class A
{
public:
A() : b_(*(new B))
{}
private:
B& b_;
};
int main()
{
A a;
return 0;
}
该语言允许这样做,但是,如您所写,存在内存泄漏。你有一个new
,但没有相应的delete
- 你需要在这里写析构函数,是这样的:
A::~A() {
delete &b_;
}
现在,虽然这是合法的,很是怪异。一个指针也可以做得很好,并且可能会更好地表达正在发生的事情。智能指针可以帮助您避免泄漏,并且可能适用。
你当然在泄漏记忆;每个new
需要与delete
匹配。
除非有一个很好的理由来动态分配它,否则你最好是让b_
成为一个对象。否则,请根据您的建议使用智能指针,或者在您的析构函数中使用智能指针(或不推荐)delete
,记住要使复制构造函数和复制指派正常工作。在最后一种情况下,它是有效的(但有点不寻常),因为它是一个参考而不是指针。
这个决定实际上取决于您希望课程在复制时的表现。在第一种情况下,它会复制整个对象;在第二种情况下,它将如智能指针所定义的那样工作;在第三种情况下,它的行为将与您实施的复制构造函数/赋值相同。
+1最后一段:) – 2010-08-19 17:10:48
标记为答案? – batman 2013-05-20 19:37:59
是的,它在C++中是允许的。
当然,使用智能指针更安全。
然后你不应该担心在析构函数中清理分配的内存。
像这样:
#include <memory>
class A {
public:
A() : p_b(new B())
{}
someMethod() {
return p_b->something();
}
private:
std::auto_ptr<B> p_b;
};
int main()
{
A a;
return 0;
}
我编辑了使用语法高亮的答案 - 选择代码块,然后按下小按钮'010 ...'。我也使它更加紧凑,使屏幕真实状态达到最佳状态。 (我刚刚看到,我忘记纠正'someMethod'的'return'声明...在那里添加一个类型:) – 2010-08-19 17:06:18
'auto_ptr'不会像你期望的那样表现 - 这将我们带回Mike关于复制c-tors和赋值运算符的观点。或者,你可以使用'boost :: shared_ptr'。所有('boost :: shared_ptr',这个例子,编写一个复制对象的副本c-tor)行为不同,所以你需要评估情况,看看哪个是正确的。 – Thanatos 2010-08-19 17:11:33
我想补充到说了些什么,唯一的一点是,即使你是在这意味着b
总是以一个值开始,在构造函数中分配内存我会稍微改变贾斯汀写的东西。在我致电delete
之前,我总是检查NULL
,然后在释放它之后将指针设置为NULL
。在析构函数设置中,指向NULL
的指针是毫无意义的,但是为了一致性而存在。
class A
{
public:
A():b_(new B)
~A() { if (b) { delete b; b = NULL; } }
{}
private:
B* b_;
}
'delete NULL;'在C++中是一个有效的语句:它什么也不做。 – Thanatos 2010-08-19 17:07:23
我建议你打破这个习惯;检查null,并设置为null,只是无意中膨胀了代码。而且,再一次,如果你写一个析构函数,你几乎总是需要修复复制语义。 – 2010-08-19 17:11:29
好的建议。旧习惯很难消退,但我会与Thanatos的评论一起记住这一点。谢谢。 – linuxuser27 2010-08-19 17:26:41
并记住:如果你有一个非平凡的析构函数,你几乎总是需要对复制构造函数和复制赋值进行排序。 – 2010-08-19 16:56:28
然后再......不要。如果你想管理动态分配的内存,请明确指出:使用指针。如果你想把它做好,那就制作一些聪明的指针。将动态分配的内存隐藏在引用后面会让您更加复杂地推断代码,当您或其他人需要稍后处理代码时。 – 2010-08-19 17:01:22
@David:这是对我的意思的一个更好的措辞解释,“一个指针会......更好地传达正在发生的事情。” – Thanatos 2010-08-19 17:05:03