关于boost::shared_ptrs的陷阱有几个有趣的问题.在其中一个中,有一个有用的提示,以避免指向boost::shared_ptr<Base>和boost::shared_ptr<Derived>相同的类型对象,Derived因为它们使用不同的引用计数,并可能过早地破坏对象.
我的问题:是否安全兼得boost::shared_ptr<T>并boost::shared_ptr<const T>点型的同一个对象T,还是将导致同样的问题?
这个问题总是让我很烦恼,特别是当我用Qt编程的时候.由于Qt使用对象所有权树,因此传递指针(例如via)myBoostSharedPtr.get()可以隐式转移所有权.现在考虑一些Qt对象被破坏并且整个对象树被破坏但智能指针仍然存在的情况,例如作为不同类的成员.如果之后智能指针被删除会发生什么?双重删除所有令人讨厌的后果?一些智能指针实现会阻止这种情况吗?
我想要一个带有指针成员变量的类.该指针应指向可以堆栈分配或堆分配的对象.但是,此指针不应具有任何所有权.换句话说,当指针超出范围时,根本不应该调用delete.我认为原始指针可以解决问题...但是,我不确定是否有比原始指针更好的C++ 11方法?
例:
class foo{
public:
bar* pntr
};
int main(){
bar a;
foo b;
b.pntr=&a;
}
Run Code Online (Sandbox Code Playgroud) 我们都知道RAW指针需要用某种形式的智能指针包装来获得Exception安全内存管理.但是当涉及指针容器时,问题变得更加棘手.
std容器坚持包含的对象是可复制的,因此这排除了使用std :: auto_ptr,尽管你仍然可以使用boost :: shared_ptr等.
但是也有一些明确设计的boost容器可以安全地保存指针:
请参阅指针容器库
问题是:在什么条件下,我更喜欢在smart_pointers容器上使用ptr_containers?
boost::ptr_vector<X>
or
std::vector<boost::shared_ptr<X> >
Run Code Online (Sandbox Code Playgroud) 我已经使用C++一段时间了,我仍然觉得使用智能指针感觉不太舒服,我只是在编辑一些使用它们的代码时一直使用它们,从不在我自己的代码中(可能值得说我是学生).
你能解释什么是智能指针的类型,它们如何工作以及何时使用它们?
另外,在其他人编写的接口中接收或传递原始指针时,"协议"是什么?
谢谢.
这只是一个学术问题(我不会在实际代码中这样做):
如果我在我的代码中普遍使用shared_ptr <>,那么行为是否等同于Java之类的gc收集语言?
如果不是,行为将如何与gc嵌入式语言不同?与gc嵌入式语言相比,哪种C++构造会产生相同的行为?
注意:在实际编码中,我更倾向于使用RAII和严格的所有权来使用任何智能指针.我也知道其他不太通用的指针,unique_ptr <>会更有效率.这个问题只是对智能指针等价的一个问题.
我使用C++作为应用主干和Objective-C用于GUI,这很好.
但是当谈到在Objective-C++(.mm文件)中将这些代码混合在一起时,我有一些问题:
例如,在Objective-C标题中,我可以执行以下操作吗?
#include <vector>
#include <boost\shared_ptr.hpp>
@interface MyClass : NSObject {
std::vector<boost::shared_ptr<CCSprite> > m_spriteList;
}
Run Code Online (Sandbox Code Playgroud)
然后在.mm文件中,我想做
CCSprite* newSprite = [/* cocos2d stuff here... */];
m_spriteList.push_back(newSprite);
Run Code Online (Sandbox Code Playgroud)
以上代码有效吗?它肯定是在C++中,但我不确定混合C++和Objective-C和Cocos2D.
当我尝试在Objective-C中使用C++代码时,我想在Objective-C头文件中将C++对象声明为成员变量.
假设我在test.h标头中声明了一个C++类:
Test{
};
Run Code Online (Sandbox Code Playgroud)
在Objective-C头文件中,我想做
#include "test.h"
#incude <boost/scoped_ptr.hpp>
#include <vector>
@interface MyClass : NSObject {
Test* m_testObjectPtr; // (1)
boost::scoped_ptr<Test> m_testOjbSmartPtr; // (2)
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,是(2)好吗?我可以像在C++代码中一样在Objective-C中使用智能指针吗?我可以假设在Test销毁MyClass对象时会调用类析构函数吗?
或者如果(2)在Objective-C++中不合适,(1)好吗?我需要手动调用
delete m_testObjectPtr的dealloc?
是否有可能编写一个智能指针,在其构造函数中分配对象本身 - 而不是开发人员必须调用new?换句话说,而不是写:
std::unique_ptr<myClass> my_ptr(new myClass(arg1, arg2))
......可以写:
std::smarter_ptr<myClass> my_ptr(arg1, arg2)
语言语法能够表达这个吗?这会是可取的吗?可怕?我正在考虑防止这个错误(我当然是自己做的):
myFunction(std::unique_ptr<myClass>(new myClass()), std::unique_ptr<myClass>(new myClass()))
...如果第二次分配发生在第一个对象被安全地隐藏在其智能指针之前,那么首先分配哪个对象可能会泄漏.但更智能的指针实际上会使这个安全吗?
考虑以下代码:
#include <memory>
#include <iostream>
using namespace std;
struct MySharedStruct
{
int i;
};
void print_value_of_i(weak_ptr<MySharedStruct> weakPtr)
{
if (shared_ptr<MySharedStruct> sp = weakPtr.lock())
{ cout << "Value of i = " << sp->i << endl; }
else
{ cout << "Resource has expired"; }
}
int main()
{
shared_ptr<MySharedStruct> sharedPtr(new MySharedStruct() );
sharedPtr->i = 5;
weak_ptr<MySharedStruct> weakPtr;
weakPtr = sharedPtr;
print_value_of_i(weakPtr);
sharedPtr.reset(new MySharedStruct() ); // <<----- How does weak_ptr know it has expired after this line executes?
sharedPtr->i = 10; …Run Code Online (Sandbox Code Playgroud) 我只知道std::enable_shared_from_this形成这个链接.
但在阅读下面的代码后,我不知道何时使用它.
try {
Good not_so_good;
std::shared_ptr<Good> gp1 = not_so_good.getptr();
} catch(std::bad_weak_ptr& e) {
// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)
std::cout << e.what() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
上面的代码"不太好",因为shared_ptr在调用之前没有存在getptr().好的应该是:
std::shared_ptr<Good> gp1 = std::make_shared<Good>(); // having a shared_ptr at the beginning
std::shared_ptr<Good> gp2 = gp1->getptr();
Run Code Online (Sandbox Code Playgroud)
但是,如果我已经有了一个shared_ptr对象,为什么我不只是简单地编码:std::shared_ptr<Good> gp2 = gp1;这意味着我根本不需要std::enable_shared_from_this.
在我看来,使用std::enable_shared_from_this是确保多个shared_ptr对象具有相同的控制块,以便我们可以避免双删除问题.但是如果我必须提醒自己shared_ptr在开始时创建一个,为什么我不提醒自己使用shared_ptrobject来创建一个新的,而不是使用原始指针?
c++ ×10
smart-pointers ×10
shared-ptr ×3
boost ×2
c++11 ×2
containers ×1
java ×1
objective-c ×1
pointers ×1
qt ×1
refcounting ×1
stl ×1
weak-ptr ×1