我通常对pimpl使用boost :: scoped_ptr(出于一个原因,因为如果我忘记处理复制构造函数,我就不会感到惊讶)
但是,使用模板,我不能将析构函数放在完全定义impl的cpp文件中,以满足scoped_ptr析构函数的要求.无论如何它确实有效,但我不确定它是否能够保证工作或只是偶然.有一些"最佳实践"或标准吗?scoped_ptr是非可复制类中pimpls的最佳智能指针吗?
template <class T> class C {
public:
C(){}
~C(){}
private:
boost::scoped_ptr<T> pimpl_;
};
Run Code Online (Sandbox Code Playgroud) 我在这样的小函数中使用scoped_ptr.所以我不必调用删除.对于这种用法,这是否有点过分?我的团队成员更喜欢原始指针和删除.如果碰巧在非常关键的路径中使用scoped_ptr,那么使用它的成本是多少?这不应该是内联的,并且完全等同于在优化的二进制文件中使用普通删除吗?
void myfunc()
{
boost::scoped_ptr<myobj> objptr = someFactory::allocate();
callsomeotherfunc(objptr.get());
}
Run Code Online (Sandbox Code Playgroud) 我想在我的c ++应用程序中使用智能指针.
我应该包含哪个头文件来使用std scoped_ptr?
所以我尝试为类创建创建一些boost.extension函数的包装器.所以我创建了一个函数:
template <class BaseClass, class ConstructorType>
boost::scoped_ptr<BaseClass> get_class (shared_library & lib, std::string class_name, ConstructorType value ) {
map<string, factory<BaseClass, ConstructorType> > lib_factories = get_factories<BaseClass, ConstructorType>(lib);
return boost::scoped_ptr<BaseClass> lib_class(lib_factories[class_name].create(value));
}
Run Code Online (Sandbox Code Playgroud)
哪个叫:
template <class BaseClass, class ConstructorType>
map<string, factory<BaseClass, ConstructorType> > get_factories (shared_library & lib) {
type_map lib_types;
if (!lib.call(lib_types)) {
cerr << "Types map not found!" << endl;
cin.get();
}
map<string, factory<BaseClass, ConstructorType> > lib_factories(lib_types.get());
if (lib_factories.empty()) {
cerr << "Producers not found!" << endl;
cin.get();
}
return lib_factories;
}
Run Code Online (Sandbox Code Playgroud)
但最后并不是那么重要.什么是重要的 …
我的团队对特定上下文的指针容器使用存在一些分歧.请考虑:
int main() {
// Top level. This is an important fact to the context
// i.e. that the following instance is at this level
// so that its members are essentially at program scope.
MainClass mainClass;
mainClass.run();
}
// A instance of a class derived from Buffer does something very complex
// (it has various handles to resources/allocated memory) so that you would
// never want to copy an instance.
class Buffer;
class MainClass {
#make_decision_here_based_on_stack_overflow_responses
shared_ptr<Buffer> buffer; // …Run Code Online (Sandbox Code Playgroud) 我正在玩增强范围指针,我不明白这种行为:
#include <iostream>
#include <boost/scoped_ptr.hpp>
int main()
{
boost::scoped_ptr<int> p{new int{1}};
std::cout << &p << '\n';
p.reset(new int {2});
std::cout << &p << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
0x7fff5fbff650
0x7fff5fbff650
Run Code Online (Sandbox Code Playgroud)
复位功能不应该改变p指向的地址吗?如果使用范围数组而不是范围指针并打印上面代码中第一个元素指向的地址,则会出现这种情况.
为什么以下代码不允许调用foo(ptr)?
#include <boost/scoped_ptr.hpp>
struct A {
virtual ~A() {}
};
struct B: public A {};
void foo(boost::scoped_ptr<A>& a) {}
void goo(A& a) {}
int main() {
boost::scoped_ptr<B> ptr(new B);
foo(ptr);
B b;
goo(b);
}
Run Code Online (Sandbox Code Playgroud)
我们传递引用的相应表单按预期工作.我们不应该使用boost scoped_ptr做多态吗?
g ++ with boost 1.49给了我:
error: invalid initialization of reference of type ‘boost::scoped_ptr<A>&’ from expression of type ‘boost::scoped_ptr<B>’
Run Code Online (Sandbox Code Playgroud) 如果经常发现自己使用这样的代码:
boost::scoped_ptr<TFoo> f(new TFoo);
Bar(f.get()); // call legacy or 3rd party function : void Bar (TFoo *)
Run Code Online (Sandbox Code Playgroud)
现在,我认为智能指针可以轻松地将隐式转换运算符定义回"原始"指针类型,这将允许此代码仍然有效,并简化旧代码的"智能化"
Bar(f);
Run Code Online (Sandbox Code Playgroud)
但是,它们至少不是,而不是我发现的那些.为什么?
一般来说,我都遵循Google风格指南,我觉得这与我看待事物的方式很吻合.我也几乎完全使用boost :: scoped_ptr,这样只有一个经理拥有特定对象的所有权.然后我传递了裸指针,这个想法是我的项目的结构使得所有对象的管理器在使用它们的对象被销毁后总是被销毁.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers
这一切都很棒,但是我只是被一个令人讨厌的小内存stomp bug所困扰,其中所有者恰好在删除使用它的对象之前被删除了.
现在,在每个人都跳起来之前说我对这个模式很傻,为什么我不只是使用shared_ptr?等等,考虑一下我不希望拥有未定义的所有者语义.尽管shared_ptr会捕获这种特殊情况,但它会向系统用户发送错误消息.它说,"我不知道谁拥有这个,它可能是你!"
什么会帮助我本来是一个指向范围指针的弱指针.实际上,一个带有弱引用列表的作用域指针,当作用域指针析构时它们被清空.这将允许单一所有权语义,但给使用对象一个机会来捕捉我遇到的问题.
因此,以scoped_ptr的额外'weak_refs'指针和weak_ptr中'next_weak_ptr'的额外指针为代价,它将成为一个整洁的小单一所有者,多个用户结构.
它甚至可能只是一个调试功能,所以在'release'中,整个系统只会转回一个正常大小的scoped_ptr和一个用于弱引用的标准单指针.
所以这......我的问题是:
干杯,沙恩
我有一些关于在boost库中实现的智能指针的问题.是shared_ptr的和scoped_ptr的没有拷贝构造函数和shared_ptr的有它scoped_ptr的之间的唯一diffrence?当对象不调用复制构造函数时,我应该总是使用scoped_ptr而不是shared_ptr吗?我也不明白共享/作用域数组的想法.我不能只使用std :: vector而不是它吗?
c++ ×10
scoped-ptr ×10
boost ×6
shared-ptr ×2
pimpl-idiom ×1
pointers ×1
polymorphism ×1
structure ×1
templates ×1
weak-ptr ×1