我多年来一直在使用 C++,但在使用可能被认为是老式的环境中。具体来说,我们没有使用 auto_ptr,也不允许在构造函数中分配内存。
继续前进,我以为我已经掌握了窍门,直到……查看以下代码:
#include <memory>
#include <iostream>
using namespace std;
class Foo
{
public:
int x;
~Foo() { cout << "~Foo" << endl; }
};
class Bar
{
public:
Bar() { throw 0; }
~Bar() { cout << "~Bar" << endl; }
int y;
};
class HumBug
{
public:
HumBug();
virtual ~HumBug();
auto_ptr<Foo> foo;
auto_ptr<Bar> bar;
};
HumBug::HumBug()
{
cout << "before foo" << endl;
foo = auto_ptr<Foo>(new Foo);
cout << "after foo" << endl;
bar = auto_ptr<Bar>(new Bar);
cout << "after bar" << endl;
}
HumBug::~HumBug()
{
cout << "~HumBug" << endl;
}
int main()
{
try
{
HumBug humbug;
}
catch (...)
{
}
return 0;
}
我知道不会调用 HumBug 的析构函数,因为在调用 HumBug 构造函数期间会发生异常。我期待创建的 Foo 属性会泄漏。但是 valgrind 说没关系:
==4985== Memcheck, a memory error detector
==4985== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4985== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4985== Command: ./a.out
==4985==
before foo
after foo
~Foo
==4985==
==4985== HEAP SUMMARY:
==4985== in use at exit: 0 bytes in 0 blocks
==4985== total heap usage: 3 allocs, 3 frees, 108 bytes allocated
==4985==
==4985== All heap blocks were freed -- no leaks are possible
==4985==
==4985== For counts of detected and suppressed errors, rerun with: -v
==4985== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
那么是不是虽然没有调用析构函数,但属性'仍然被可靠地破坏了?我在想,为了可靠地清理它,我必须将 HumBug 的构造函数重写为:
HumBug::HumBug()
{
auto_ptr<Foo> new_foo (new Foo);
auto_ptr<Bar> new_bar (new Bar);
// no exceptions after this point
foo = new_foo;
bar = new_bar;
}
但似乎情况并非如此。
我可以依靠这个吗?