我定义了一个类 foo 如下:
class foo {
private:
static int objcnt;
public:
foo() {
if(objcnt==8)
throw outOfMemory("No more space!");
else
objcnt++;
}
class outOfMemory {
public:
outOfMemory(char* msg) { cout << msg << endl;}
};
~foo() { cout << "Deleting foo." << endl; objcnt--;}
};
int foo::objcnt = 0;
这是主要功能:
int main() {
try {
foo* p = new foo[3];
cout << "p in try " << p << endl;
foo* q = new foo[7];
}catch(foo::outOfMemory& o) {
cout << "Out-of-memory Exception Caught." << endl;
}
}
很明显,“foo* q = new foo[7];”行只成功创建了5个对象,第6个对象抛出Out-of-memory异常。但事实证明,只有 5 个析构函数调用,并且 p 指向的位置存储的 3 个对象的数组没有调用析构函数。所以我想知道为什么?为什么程序只调用这 5 个对象的析构函数?
“原子”C++ 分配和构造函数are正确且异常安全:如果new T
;抛出,没有泄漏,如果new T[N]
沿途扔到任何地方,所有已经构建的东西都会被摧毁。所以没什么好担心的。
现在题外话:
你什么always必须担心正在使用超过一个 new
以任何单一责任单位表达。基本上,你必须考虑任何new
表达为一个烫手山芋,需要被一个完整构建的、负责任的守护对象吸收。
考虑new
and new[]
严格作为库构建块:您永远不会在高级用户代码中使用它们(也许除了单个new
在构造函数中),并且仅在库类中。
To wit:
// BAD:
A * p = new A;
B * q = new B; // Ouch -- *p may leak if this throws!
// Good:
std::unique_ptr<A> p(new A);
std::unique_ptr<B> q(new B); // who cares if this throws
std::unique_ptr<C[3]> r(new C[3]); // ditto
As another aside: The standard library containers implement a similar behaviour: If you say resize(N)
(growing), and an exception occurs during any of the constructions, then all of the already-constructed elements are destroyed. That is, resize(N)
either grows the container to the specified size or not at all. (E.g. in GCC 4.6, see the implementation of _M_fill_insert()
in bits/vector.tcc
for a library version of exception-checked range construction.)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)