2010-08-19 46 views

回答

1

该语言允许这样做,但是,如您所写,存在内存泄漏。你有一个new,但没有相应的delete - 你需要在这里写析构函数,是这样的:

A::~A() { 
    delete &b_; 
} 

现在,虽然这是合法的,很是怪异。一个指针也可以做得很好,并且可能会更好地表达正在发生的事情。智能指针可以帮助您避免泄漏,并且可能适用。

+2

并记住:如果你有一个非平凡的析构函数,你几乎总是需要对复制构造函数和复制赋值进行排序。 – 2010-08-19 16:56:28

+2

然后再......不要。如果你想管理动态分配的内存,请明确指出:使用指针。如果你想把它做好,那就制作一些聪明的指针。将动态分配的内存隐藏在引用后面会让您更加复杂地推断代码,当您或其他人需要稍后处理代码时。 – 2010-08-19 17:01:22

+0

@David:这是对我的意思的一个更好的措辞解释,“一个指针会......更好地传达正在发生的事情。” – Thanatos 2010-08-19 17:05:03

5

你当然在泄漏记忆;每个new需要与delete匹配。

除非有一个很好的理由来动态分配它,否则你最好是让b_成为一个对象。否则,请根据您的建议使用智能指针,或者在您的析构函数中使用智能指针(或不推荐)delete,记住要使复制构造函数和复制指派正常工作。在最后一种情况下,它是有效的(但有点不寻常),因为它是一个参考而不是指针。

这个决定实际上取决于您希望课程在复制时的表现。在第一种情况下,它会复制整个对象;在第二种情况下,它将如智能指针所定义的那样工作;在第三种情况下,它的行为将与您实施的复制构造函数/赋值相同。

+1

+1最后一段:) – 2010-08-19 17:10:48

+0

标记为答案? – batman 2013-05-20 19:37:59

1

是的,它在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; 
} 
+0

我编辑了使用语法高亮的答案 - 选择代码块,然后按下小按钮'010 ...'。我也使它更加紧凑,使屏幕真实状态达到最佳状态。 (我刚刚看到,我忘记纠正'someMethod'的'return'声明...在那里添加一个类型:) – 2010-08-19 17:06:18

+0

'auto_ptr'不会像你期望的那样表现 - 这将我们带回Mike关于复制c-tors和赋值运算符的观点。或者,你可以使用'boost :: shared_ptr'。所有('boost :: shared_ptr',这个例子,编写一个复制对象的副本c-tor)行为不同,所以你需要评估情况,看看哪个是正确的。 – Thanatos 2010-08-19 17:11:33

0

我想补充到说了些什么,唯一的一点是,即使你是在这意味着b总是以一个值开始,在构造函数中分配内存我会稍微改变贾斯汀写的东西。在我致电delete之前,我总是检查NULL,然后在释放它之后将指针设置为NULL。在析构函数设置中,指向NULL的指针是毫无意义的,但是为了一致性而存在。

class A 
{ 
public: 

    A():b_(new B) 
    ~A() { if (b) { delete b; b = NULL; } } 
    {} 

private: 
    B* b_; 

} 
+3

'delete NULL;'在C++中是一个有效的语句:它什么也不做。 – Thanatos 2010-08-19 17:07:23

+3

我建议你打破这个习惯;检查null,并设置为null,只是无意中膨胀了代码。而且,再一次,如果你写一个析构函数,你几乎总是需要修复复制语义。 – 2010-08-19 17:11:29

+0

好的建议。旧习惯很难消退,但我会与Thanatos的评论一起记住这一点。谢谢。 – linuxuser27 2010-08-19 17:26:41