当使用pImpl习语时,最好使用a boost:shared_ptr而不是std::auto_ptr?我确定我曾经读过增强版更加异常友好吗?
class Foo
{
public:
Foo();
private:
struct impl;
std::auto_ptr<impl> impl_;
};
class Foo
{
public:
Foo();
private:
struct impl;
boost::shared_ptr<impl> impl_;
};
Run Code Online (Sandbox Code Playgroud)
[编辑]使用std :: auto_ptr <>是否总是安全的,或者是否需要使用替代的boost智能指针?
从他的STL书中读到Jossutis对auto_ptr的解释之后,我得到了一个强烈的印象,即我会尝试使用它的任何任务100%失败,因为很多auto_ptr的陷阱之一.
我的问题是:有没有任何真正的生活任务,其中auto_ptr真的很有用,并且适合那里吗?
我正在使用auto_ptr<>它使用类指针类型的数组,所以我如何为它赋值.
例如
auto_ptr<class*> arr[10];
如何为arr数组赋值?
如果我使用声明一个临时自动删除的字符缓冲区
std::auto_ptr<char> buffer(new char[n]);
Run Code Online (Sandbox Code Playgroud)
然后当缓冲区超出范围时自动删除缓冲区.我假设使用delete删除缓冲区.
但是缓冲区是使用new []创建的,因此严格来说应该使用delete []删除缓冲区.
这种不匹配可能导致内存泄漏的可能性有多大?
我有一个这样的课:
class Inner;
class Cont
{
public:
Cont();
virtual ~Cont();
private:
Inner* m_inner;
};
Run Code Online (Sandbox Code Playgroud)
在.cpp中,构造函数创建了一个Innerwith new和析构函数delete的实例.这工作得很好.
现在我想更改此代码以便使用,auto_ptr所以我写道:
class Inner;
class Cont
{
public:
Cont();
virtual ~Cont();
private:
std::auto_ptr<Inner> m_inner;
};
Run Code Online (Sandbox Code Playgroud)
现在,构造函数初始化了auto_ptr,而析构函数什么都不做.
但它不起作用.当我实例化这个类时,问题似乎就出现了.我收到这个警告:
警告C4150:删除指向不完整类型'Inner'的指针; 没有破坏者叫
好吧,这显然非常糟糕,我明白为什么会发生这种情况,编译器不知道Inner实例化模板的时候auto_ptr<Inner>
所以我的问题:是否有一种方法可以使用auto_ptr前向声明,就像我在仅使用普通指针的版本中所做的那样?我
必须向#include每个班级宣布一个指针是一个巨大的麻烦,有时候,这是不可能的.这个问题通常是如何处理的?
我写了这篇文章并得到了一些让我困惑的评论.
它基本上归结为我已经看到T2仅用作模板参数并错误地跳到结论我因此可以利用前向声明的机会:
struct T2;
struct T1
{
std::auto_ptr<T2> obj;
};
Run Code Online (Sandbox Code Playgroud)
如果我不继续在T2同一个TU中定义某个地方,则调用UB ,因为std::auto_ptr<T2>调用delete其内部T2*,并调用delete指向不完整类型的对象的指针,其完整类型具有非平凡的析构函数是未定义的:
[C++11: 5.3.5/5]:如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的.
我碰巧使用的GCC工具链 - v4.3.3(Sourcery G ++ Lite 2009q1-203) - 非常友好地通过一个注释让我知道:
注意:即使在定义类时声明析构函数也不会调用析构函数或特定于类的运算符delete.
虽然在其他GCC版本中似乎很难得到这种诊断.
我的抱怨是,如果delete指向不完整类型的实例的指针是不正确的而不是UB,那么发现这样的bug会容易得多,但这似乎是一个实现难以解决的问题,所以我明白为什么是UB.
但后来我被告知,如果我使用它std::unique_ptr<T2>,这将是安全和合规的.
据称n3035在20.9.10.2说:
模板参数
T的unique_ptr可能是一个不完整的类型.
我在C++ 11中找到的所有内容都是:
[C++11: 20.7.1.1.1]:/ 1类模板
default_delete用作类模板的默认删除器(销毁策略)unique_ptr./ 2模板参数
T的default_delete可能是一个不完整的类型.
但是,default_delete的operator()的确需要一个完整的类型:
[C++11: …
auto_ptr_ref文档在这里 说明了这一点
This is an instrumental class to allow certain conversions that allow auto_ptr objects to be passed to and returned from functions.
有人可以解释一下auto_ptr_ref如何帮助实现这一目标.我只是想了解auto_ptr类及其内部
在C++/CLI中,您可以在托管类中使用本机类型,因为它不允许在托管类中保存本机类的成员:在这种情况下您需要使用指针.
这是一个例子:
class NativeClass
{
....
};
public ref class ManagedClass
{
private:
NativeClass mNativeClass; // Not allowed !
NativeClass * mNativeClass; // OK
auto_ptr<NativeClass> mNativeClass; //Not allowed !
boost::shared_ptr<NativeClass> mNativeClass; //Not allowed !
};
Run Code Online (Sandbox Code Playgroud)
有没有人知道C++/CLI世界中相当于shared_ptr的东西?
编辑:感谢您的建议,"1800-信息".根据您的建议,我检查了STL.Net,但它仅适用于Visual Studio 2008,它提供容器+算法,但没有智能指针.
我遇到了一个对我没有多大意义的编译器错误:
#include <memory>
using namespace std;
auto_ptr<Table> table = db->query("select * from t");
Run Code Online (Sandbox Code Playgroud)
错误:从'Table*'转换为非标量类型'std :: auto_ptr <Table>'
但是,以下行确实有效:
auto_ptr<Table> table(db->query("select * from t"));
Run Code Online (Sandbox Code Playgroud)
这个构造函数的定义是什么阻止它像我期望的那样工作?我认为初始化声明使用了构造函数.
这是我auto_ptr的构造函数(来自SGI STL):
explicit
auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
Run Code Online (Sandbox Code Playgroud) 我听说自动指针拥有自己的对象,而共享指针可以有许多指向它们的对象.为什么我们不一直使用共享指针.
与此相关的是智能指针,人们可以将这个术语与共享指针互换使用.它们是一样的吗?
auto-ptr ×10
c++ ×9
stl ×5
shared-ptr ×3
arrays ×1
boost ×1
c++-cli ×1
c++11 ×1
gcc ×1
memory-leaks ×1
pointers ×1
unique-ptr ×1