make_shared()的可调试替换 [英] Debuggable replacement for make_shared()
问题描述
使用gcc 4.6.2,如果构造函数引发异常,make_shared()会给出无用的回溯(显然是由于重新抛出).我正在使用make_shared()节省一些键入内容,但这是show stopper.我创建了一个替代 make_shrd(),它可以进行正常的回溯.我正在使用gdb 7.3.1.
Using gcc 4.6.2, make_shared() gives a useless backtrace (apparently due to some rethrow) if a constructor throws an exception. I'm using make_shared() to save a bit of typing, but this is show stopper. I've created a substitute make_shrd() that allows a normal backtrace. I'm using gdb 7.3.1.
我担心:
- make_shared()下不好的回溯是我自己的错
- 我的替代品make_shrd()会给我带来一些细微的问题.
这是一个演示:
#include <memory>
#include <stdexcept>
using namespace std;
class foo1
{
public:
foo1( const string& bar, int x ) :m_bar(bar), m_x(x)
{
throw logic_error( "Huh?" );
}
string m_bar;
int m_x;
};
class foo2
{
public:
foo2( const string& bar, int x ) : m_foo1(bar,x)
{}
foo1 m_foo1;
};
// more debuggable substitute for make_shared() ??
template<typename T, typename... Args>
std::shared_ptr<T> make_shrd( Args... args )
{
return std::shared_ptr<T>( new T(args...));
}
int main()
{
auto p_foo2 = make_shared<foo2>( "stuff", 5 ); // debug BAD!!
// auto p_foo2 = make_shrd<foo2>( "stuff", 5 ); // debug OK
// auto p_foo2 = new foo2( "stuff", 5 ); // debug OK
// auto p_foo2 = shared_ptr<foo2>(new foo2( "stuff", 5 )); // debug OK
return (int)(long int)p_foo2;
}
编译:
g++ -g -std=c++0x -Wall -Wextra main.cpp
已调试:
gdb a.out
make_shared()回溯是垃圾,无法显示堆栈到异常点.所有其他选项提供了合理的回溯.
The make_shared() backtrace is junk that does not show the stack to the point of the exception. All the other options provide a sane backtrace.
预先感谢您的帮助和建议.
Thanks in advance for help and suggestions.
推荐答案
您对 make_shrd()
的实现失去了仅分配一块内存的功能: std :: make_shared()
做两件事:
Your implementation of make_shrd()
looses the ability to allocate just one chunk of memory: std::make_shared()
does two things:
- 避免重复编写类型(如果分配的类型和所需的
std :: shared_ptr< T>
的类型相同,则后者是基类的) - 它将共享对象和对象描述符的分配合并为一个分配
- it avoids duplicating of writing the type (if the type of the allocation and the type of the desired
std::shared_ptr<T>
are the same rather than the latter being for a base class) - it combines allocation of the shared object and the object's descriptor into just one allocation
std :: make_shared()
的主要目的实际上是第二个功能.我没有看过实现,但是我怀疑这实际上也是导致您出现问题的部分.除此之外,一旦修复了参数转发问题,我看不出您的实现会变得更糟的任何原因:
The main purpose of std::make_shared()
is actually the second feature. I haven't looked at the implementation but I suspect that this is also the part which actually causes you problems. Other than that, I don't see any reason why your implementation is any worse once you fix forwarding of arguments:
template<typename T, typename... Args>
std::shared_ptr<T> make_shrd(Args&&... args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
这篇关于make_shared()的可调试替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!