我对使用的最佳实践几乎没有疑问shared_ptr.
问题1
复制shared_ptr便宜吗?或者我是否需要将其作为参考传递给我自己的帮助函数并返回值?就像是,
void init_fields(boost::shared_ptr<foo>& /*p_foo*/);
void init_other_fields(boost::shared_ptr<foo>& /*p_foo*/);
boost::shared_ptr<foo> create_foo()
{
boost::shared_ptr<foo> p_foo(new foo);
init_fields(p_foo);
init_other_fields(p_foo);
}
Run Code Online (Sandbox Code Playgroud)
问题2
我应该boost::make_shared用来构建一个shared_ptr吗?如果是,它提供了哪些优势?make_shared当T没有无参数构造函数时,我们如何使用?
问题3
怎么用const foo*?我找到了两种方法来做到这一点.
void take_const_foo(const foo* pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo.get());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要么
typedef boost::shared_ptr<foo> p_foo;
typedef const boost::shared_ptr<const foo> const_p_foo;
void take_const_foo(const_p_foo pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题4
我怎样才能返回,检查NULL …
根据cppreference.com,std::shared_ptr提供了一整套相对运算符(==,!=,<,...),但未指定比较的语义.我假设他们比较了引用对象的底层原始指针,并且std :: weak_ptr和std :: unique_ptr也是如此.
出于某些目的,我宁愿让相对运算符根据比较引用的对象(而不是指向它们的指针)来对智能指针进行排序.这已经是我做了很多事情,但是我自己的"哑指针"除了相对运算符之外,其行为大部分都像原始指针.我也想用标准的C++ 11智能指针做同样的事情.所以...
是否可以从C++ 11智能指针(shared_ptr,weak_ptr和unique_ptr)继承并覆盖相对运算符?
我需要注意哪些鬼鬼祟祟的问题?例如,我需要实现或使用任何其他方法using来确保工作正常吗?
对于最终的懒惰,是否有可用的库模板自动执行此操作?
我希望这是"当然你可以做到这一点,白痴!" 有点事,但我有点不确定,因为标准库中有一些类(std::map至少是容器)你不应该继承.
有关智能指针的MSDN页面包含有关在参数列表中创建智能指针的提升警告:
始终在单独的代码行上创建智能指针,从不在参数列表中创建智能指针,以便由于某些参数列表分配规则而不会发生细微的资源泄漏.
它所指的参数列表分配规则是什么?在什么情况下会发生资源泄漏?
我正在尝试使用智能指针为类成员变量创建一个访问器.这是代码:
class MyResource
{
};
class MyClass
{
public:
std::unique_ptr<MyResource> getResource();
private:
std::unique_ptr<MyResource> resource;
};
std::unique_ptr<MyResource> MyClass::getResource()
{
return this->resource;
}
Run Code Online (Sandbox Code Playgroud)
我试图编译这个错误:
无法访问类'std :: unique_ptr <_Ty>'中声明的私有成员
添加.get到this->resource当然不会,因为返回类型的变化工作.
我不应该在这里使用unique_ptr吗?这只是一个语法问题吗?我完全走错了路吗?
我的智能指针背景: 我已经使用了几年的普通指针,部分原因是因为我找不到何时使用哪种智能指针以及如何使用它们的可靠解释.我已经厌倦了找借口,所以我只是潜入.我想我明白智能指针是什么以及为什么要使用它们,但我对细节知之甚少.目前,我完全迷失在关于智能指针的 无尽 问答中 .
是否有一个原因unique_ptr::reset没有重载采用a const deleter&和deleter&&匹配其构造函数,将其作为第二个参数?
存储的删除器unique_ptr将被复制分配或移动分配参数来自reset.如果删除器是不可复制的或不可移动的,则调用相应的重载reset将无法编译.这似乎与构造函数的一致行为.
我想将该make_shared<T>函数与派生类一起使用,如下所示
class Base {
public:
typedef std::shared_ptr<Base> Ptr;
};
class Derived : public Base {};
Base::Ptr myPtr = std::make_shared(/* Derived() */ );
Run Code Online (Sandbox Code Playgroud)
如何告诉make_shared构建这样的对象?
我想避免经典
Base::Ptr ptr = Base::Ptr(new Derived());
Run Code Online (Sandbox Code Playgroud)
在make_shared函数中使用单个alloc.
我试图弄清楚是否可以创建一个指向不同类型的共享指针数组.例如,类似的东西:
vector<shared_ptr<**???**>> v;
v.push_back(shared_ptr<int>(new int));
v.push_back(shared_ptr<MyClass>(new MyClass()));
Run Code Online (Sandbox Code Playgroud)
或任何其他方式通过shared_ptr而不知道其类型.
我正在编写一个应该从抽象基类派生的类.我无法更改抽象基类.该类将作为shared_ptr抽象基类保存.是否可以从抽象基类继承而且 enable_shared_from_this?像这样:
class IWidget {
public:
virtual ~IWidget(){}
// ...
};
class Widget : public std::enable_shared_from_this<Widget>, public IWidget {
protected:
Widget(); // protected, use create
public:
static std::shared_ptr<IWidget> create() {
return std::shared_ptr<IWidget>(new Widget(init));
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
这里有更完整的代码似乎有效.
我能找到的大多数例子enable_shared_from_this都在基类上.在这种情况下,我无法更改基类.可以使用多重继承并在派生类上使用它吗?
我有点担心,我只能保证enable_shared_from_this只有在我创建了一个shared_ptr<Widget>但是在这种情况下我才能创建一个shared_ptr<IWidget>.
更新:我注意到的一件有趣的事情是,如果我将create方法更改为:
IWidget* w = new Widget(init);
return std::shared_ptr<IWidget>(w);
Run Code Online (Sandbox Code Playgroud)
我尝试使用时遇到运行时错误shared_from_this().我认为这是有道理的.shared_ptr有一个带有"可转换"指针的模板化构造函数.除非shared_ptr构造函数知道它正在采取Widget它不知道它来自enable_shared_from_this …
Rust 文档涵盖的范围Rc<RefCell<T>>非常广泛,但没有RefCell<Rc<T>>涉及我现在遇到的 。
这些是否有效地给出了相同的结果?它们之间有重要区别吗?
我正在使用android NDK r8d和eclipse Juno.我试图编译它使用C++ 11的东西像C++代码mutex,lock_guard,shared_ptr等在Eclipse一个原生Android项目.
我得到的错误如下:
"错误:'shared_ptr'不是'std'的成员"
"致命错误:互斥:没有这样的文件或目录"
我在这里遇到了类似的问题.它似乎对他们有效,但那里的解释并不完整,所以我无法让它为我工作.
我加入"NDK_TOOLCHAIN_VERSION=4.7"到Application.mk和"LOCAL_CFLAGS += -std=c++11"到Android.mk文件中.它仍然没有编译.
在上面的链接中它说:
"确保标准库包含路径(如/android-ndk-r8d/sources/cxx-stl/gnu-libstdc++/4.7/include)在目标设置中."
我如何以及在何处插入?
我也在eclipse IDE中遇到错误(在编译之前在源代码上).我知道我应该定义"__GXX_EXPERIMENTAL_CXX0X__"解决它们,但我只是不知道把它放在哪里.
所以,如果有人能够发布一个答案,并详细解释如何编译和使用C++ 11进行eclipse工作,那就太好了.
smart-pointers ×10
c++ ×9
c++11 ×7
shared-ptr ×2
android-ndk ×1
gcc ×1
inheritance ×1
rust ×1
stl ×1