使用gcc 4.6.2,如果构造函数抛出异常,make_shared()会给出无用的回溯(显然是由于某些重新抛出)。我正在使用make_shared()来节省一些打字,但这是显示停止。我创建了一个允许正常回溯的替换 make_shrd()。我正在使用gdb 7.3.1。
我很担心:
这是一个演示:
#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()回溯是垃圾,它不会将堆栈显示到异常点。所有其他选项都提供了理智的回溯。
提前感谢您的帮助和建议。
答案 0 :(得分:4)
make_shrd()
的实现失去了只分配一块内存的能力:std::make_shared()
做了两件事:
std::shared_ptr<T>
的类型相同而不是后者用于基类) std::make_shared()
的主要目的实际上是第二个功能。我没有看过实现,但我怀疑这也是导致你出现问题的部分。除此之外,我没有看到任何理由为什么你的实现在修复转发参数后更糟糕了:
template<typename T, typename... Args>
std::shared_ptr<T> make_shrd(Args&&... args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}