- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在开发一个使用分配器来管理资源的容器类。我将尝试简要介绍一下我目前为调整容器大小所做的工作。 (真实的不是一维的,但方案是相同的,因为分配的数据是连续的。)
所有我不清楚的地方都标记为 [[[ x ]]]。
template<typename T>
class example
// ...
注意事项:
调整大小的来源(size_t):
void resize (size_type const & new_size)
{
if (new_size == 0U)
{ // we resize to zero, so we just remove all data
clear();
}
else if (new_size != size())
{ // we don't go to zero and don't remain the same size
size_type const old_size = size();
pointer new_mem(nullptr);
try
{
new_mem = _Allocate(new_size);
}
catch (std::bad_alloc e)
{
// [[[ 1 ]]]
}
size_type counter(0);
for (size_type i=0; i<new_size; ++i)
{
try
{
if (i<size())
_A.construct(new_mem + i, const_cast<const_reference>(*(_begin+i)));
// [[[ 2 ]]]
else
_A.construct(new_mem + i);
++counter;
}
catch (...) // [[[ 3 ]]]
{
// [[[ 4 ]]]
}
}
clear();
_begin = new_mem;
_end = _begin + new_size;
}
}
我应该在这里调用 clear() 并重新抛出,还是调用当前对象的析构函数,如果我没有在此处捕获?
在这里使用 const_cast() 或 std::move() 转换为右值引用怎么样?这个中断异常安全吗?
如果我移动构造,比方说 10 个元素中的 9 个,并且元素 10 在移动构造时抛出一些东西,我将失去 10 个对象中的 9 个!?
我读到应该避免使用 catch (...)
。不过,我不知道还有没有其他的可能。有没有办法在不知道构造函数是否会向我抛出或抛出什么的情况下避免使用通用捕获?
我认为这里的正确步骤是:
这是正确的吗?
最佳答案
你真的想避免所有的try
/catch
东西并使用 RAII 来确保正确的资源清理。例如:
void resize (size_type const & new_size)
{
example<T> tmp(_A); // assuming I can construct with an allocator
// If the allocation throws then the exception can propogate without
// affecting the original contents of the container.
tmp._end = tmp._begin = tmp._A.allocate(new_size);
for (size_type i = 0; i < std::min(size(), new_size); ++i)
{
tmp._A.construct(tmp._begin + i, _begin[i]);
++tmp._end; // construction successful, increment _end so this
// object is destroyed if something throws later
}
for (size_type i = size(); i < new_size; ++i)
{
tmp._A.construct(tmp._begin + i);
++tmp._end; // as above
}
// OK, the copy of old objects and construction of new objects succeeded
// now take ownership of the new memory and give our old contents to the
// temporary container to be destroyed at the end of the function.
std::swap(_begin, tmp._begin);
std::swap(_end, tmp._end);
}
注意事项:
您说“clear()
为 [_begin,_end)
中的所有元素调用 _A.destroy()
并且_A.deallocate(_begin,size())
”。为简单起见,我假设 deallocate
并不真正关心 size()
参数,这对某些分配器来说是正确的。如果这很重要,那么您可能希望 example
有一个“容量”的概念和一个 _capacity
或 _end_of_storage
成员。将大小 与容量 分开将使清理更易于编写且更可靠。
您已经在析构函数(和/或它调用的函数)中编写了正确的清理代码。通过使用临时容器,我可以重用该代码而不必复制它。
通过使用本地对象,我可以避免所有 try
/catch
block ,并依靠本地对象的自动销毁来清理资源。
关于c++ - 如何安全地处理容器类中的异常/异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16577337/
我是一名优秀的程序员,十分优秀!