唯一的区别是移动语义boost::scoped_ptr<T>和移动语义std::unique_ptr<T>的事实,std::unique_ptr<T>而boost::scoped_ptr<T>只是一个获取/重置智能指针?
scoped_ptr不能复制,并且正在删除范围之外.所以它有点受限制shared_ptr.因此,除了您真正需要限制复制操作的情况之外,shared_ptr最好使用.因为有时您不知道需要创建对象的副本或不需要.所以问题是:除了上面提到的情况之外,我们shared_ptr是否可以考虑使用更好(或推荐)代替scoped_ptr.是否scoped_ptr更快地工作shared_ptr,或者它有什么优势?
谢谢!
我在大型应用程序中工作,包含c和cpp.所有文件都保存为cpp扩展名,但代码以c风格编写.我的意思是它是定义结构而不是类通过malloc和realloc和calloc分配内存.最近他们已经安装了boost库所以我打算使用我现有的代码库所以我有一些以下的问题.
或者换句话说:
对于以下代码,如何使用std :: shared_ptr实现类似功能:
void allocateBlocks(int **ptr, int *cnt)
{
*ptr = (int*)malloc(sizeof(int) * 10);
*cnt = 10;
/*do something*/
}
int main()
{
int *p = NULL;
int count = 0;
allocateBlocks(&p, &count);
/*do something*/
free(p);
}
Run Code Online (Sandbox Code Playgroud)
我们调用一些函数,它们接受双指针并在其应用程序中填充结构并使用malloc.我们可以将这些指针分配给std :: shared_ptr吗?例如:
typedef struct txn_s
{
int s;
int d;
int *e;
} txn_t;
typedef boost::shared_ptr<txn_t> tpointer;
tpointer((txn_t*)::malloc(sizeof(txn_t),::free));
Run Code Online (Sandbox Code Playgroud) Boost的make_shared()功能有望在尝试创建时具有异常安全性shared_ptr.
为什么没有make_scoped()相应的?有一个共同的最佳做法吗?
这是一个对我来说似乎不安全的boost::scoped_ptr文档中的代码示例:
boost::scoped_ptr<Shoe> x(new Shoe);
Run Code Online (Sandbox Code Playgroud)
这行代码将按顺序执行以下三项操作:
ShoeShoeboost::scoped_ptr<Shoe>如果构造函数Shoe抛出异常, 内存将被泄露. (见R.费尔南德斯Martinho的答案) 的scoped_ptr,因为它没有被构建但不会处理重新分配.
这是疏忽吗?还是有一个我没注意到的解决方案?
可以boost::scoped_ptr在类的构造函数中初始化类的类成员吗?怎么样?
(不在初始化列表中)
范围指针的目标是什么?根据我的理解,范围指针管理代码块中的内存.如果我想在一个块中声明一个变量,我可以在堆栈上声明它而不用担心清理.
为什么在此代码中不调用析构函数?
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; throw; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
std::cout << myinst->increment() << '\n';
std::cout << myinst->increment() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
编辑
从答案中,了解当构造函数中发生异常时,不会调用析构函数.但是如果异常发生在main()中,即在完全实例化MyClass对象之后,是否会调用MyClass析构函数?如果没有,那为什么它是一个智能指针?
添加代码
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码段.boost :: scoped_ptr的析构函数在main函数的末尾调用.析构函数使用boost :: checked_delete来解除分配封装的Widget指针.
#include <boost/scoped_ptr.hpp>
#include <iostream>
class Widget;
Widget *make_widget();
int main()
{
boost::scoped_ptr<Widget> sp(make_widget());
// std::cout << sizeof(Widget) << std::endl;
}
class Widget
{
public:
Widget() {}
~Widget() { std::cout << "Widget destructor called." << std::endl; }
};
Widget *make_widget()
{
return new Widget;
}
Run Code Online (Sandbox Code Playgroud)
我希望这段代码无法编译,因为类Widget在scoped_ptr<Widget>调用析构函数时是不完整的.但是,这可以在g ++ 4.8和Visual Studio 2010上完全编译.请注意带有sizeof(Widget)main函数中表达式的注释语句.如果我取消注释它,它将无法编译暗示Widget在那一点必须是不完整的.
这种行为的正确解释是什么?
编辑:一些答案(现已删除)指向未定义的行为,但我希望在scoped_ptr析构函数中使用checked_delete 导致编译失败.FWIW,我正在使用Boost 1.55.
或者,如果我需要这样做,那么我应该只使用shared_ptr?
我刚开始使用c ++ boost库.我在许多地方读过,当使用scoped_ptr时,即使出现异常,对象也总是被销毁.
它们的行为与内置的C++指针非常相似,只是它们会自动删除在适当的时间指向的对象.智能指针在面对异常时特别有用,因为它们可确保正确销毁动态分配的对象.
我试过以下代码.
#include<boost/scoped_ptr.hpp>
class B
{
public:
B(){ std::cout<< "B constructor call\n"; }
~B(){ std::cout<<"B destructor call\n"; }
};
class A
{
public:
boost::scoped_ptr<B> b;
A():b(new B())
{
throw 1;
}
};
int main()
{
A a; return 0;
}
output:
B constructor call
terminate called after throwing an instance of 'int'
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
没有调用B的析构函数.但我使用scoped_ptr所以它应该调用B的析构函数或者我错误地解释了scoped_ptr的使用.
但如果用try catch环绕它,那么就会调用B的析构函数.
try{
A a;
} catch( ... ) {
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,A的析构函数将被调用作为所有本地分配的对象,如果try块中的异常从堆栈中删除并且我的指针包含在内部并且scoped_ptr的对象因此当scoped对象的析构函数破坏哪个最终指针.所以scoped_ptr是有用的,因为我们不必显式删除分配的内存或者我错误地解释了scoped_ptr的描述.
如果使用scoped_ptr在异常情况下如何调用B类的析构函数
c++ ×10
scoped-ptr ×10
boost ×8
shared-ptr ×3
destructor ×1
exception ×1
make-shared ×1
unique-ptr ×1