我在Qt应用程序中有一些间歇性的分段错误.我认为问题与我们(坏)的使用有关QSharedPointer.在Qt文档状态:
QSharedPointer :: QSharedPointer(T*ptr):创建一个指向ptr的QSharedPointer.指针ptr由此QSharedPointer管理,不得传递给另一个QSharedPointer对象或在此对象外删除.
我想我们两个都不能 ......:/
是否有一种OOP方式来强制管理的指针QSharedPointer不能被删除或传递给另一个QSharedPointer?
最好的解决方案是编译错误.
我有一个基类,我想将其指针转换为其派生类shared_ptr.在我的情况下,我不能使用继承enable_shared_from_this.那么还有其他有效的方法吗?
例如
typedef boost::shared_ptr <a> aPtr;
typedef boost::shared_ptr <b> bPtr;
Class a{
void fun();
}
class b : public a{
}
a::fun(){
//how to carry out this conversion below
bPtr bpointer = dynamic_cast<bPtr>(this);
}
Run Code Online (Sandbox Code Playgroud) 好吧,我一直试图绕过这个问题一段时间了,但是我不明白,有人可以告诉我为什么案例#1会抛出一个断言(BLOCK TYPE IS INVALID)?
情况1
mehodName()
{
// Get all dependents for this resource
boost::shared_ptr<std::set<std::string>> dependents = deactivatedResource->getDependendents();
// Do some stuff
} // Assertion thrown here (heap gets corrupted)
Run Code Online (Sandbox Code Playgroud)
这是这种情况下的getDependents:
boost::shared_ptr<std::set<std::string>> Resource::getDependendents()
{
return boost::shared_ptr<std::set<std::string>>(&dependents);
}
Run Code Online (Sandbox Code Playgroud)
案例#2
mehodName()
{
// Get all dependents for this resource
std::set<std::string>* dependents = deactivatedResource->getDependendents();
} // No problem !! (but an obvious leak , if I try to use delete ,then the same assertion as in case 1)
Run Code Online (Sandbox Code Playgroud)
这是这种情况下的getDependents:
std::set<std::string>* Resource::getDependendents()
{
return …Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用C++并试图了解智能指针.显然,下面的代码会崩溃(我想这是因为赋值创建了shared_ptr的副本?).有没有办法foo.Other通过调用某种set方法来保持更新ptrs[3]?
class Foo
{
public:
int X;
std::shared_ptr<Foo> Other;
Foo() : X(10) { }
};
int main()
{
Foo foo;
std::vector<std::shared_ptr<Foo>> ptrs(10);
foo.Other = ptrs[3];
std::shared_ptr<Foo> other = std::shared_ptr<Foo>(new Foo());
ptrs[3] = other;
std::cout << foo.Other->X << std::endl; // throws Access violation exception
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是我得到的异常,因为它指向null:
Test.exe中0x01219AEF处的第一次机会异常:0xC0000005:访问冲突读取位置0x00000000.Test.exe中0x01219AEF处的未处理异常:0xC0000005:访问冲突读取位置0x00000000.
我正在开发一款游戏(以及我自己的定制引擎).我有很多资产(纹理,骨架动画等),它们被多个模型使用,因此可以多次加载.
起初,我的野心更小,游戏更简单,我可以忍受一点点复制,所以shared_ptr一旦最后一个实例消失,它就会处理资源清理似乎是一个好主意.随着我的游戏的增长,越来越多的资源被多次加载,所有OpenGL状态的变化都将性能降低到了爬行状态.为了解决这个问题,我决定写一个资产管理器类.
我正在使用a unordered_map存储文件路径,std::string而c ++ 11 shared_ptr指向实际加载的资源.如果文件已经加载,我返回指针,如果没有,我调用相应的Loader类.干净利落.
不幸的是,我不能对删除说同样的话.指针的一个副本仍保留在unordered_map.目前,我遍历整个地图并.unique()每帧执行检查.这些指针结果是唯一的,从地图中删除,破坏最后一个副本并强制析构函数运行并进行清理.
迭代数百或数千个对象并不是最有效的方法.(这不是一个过早的优化,我现在处于优化阶段)是否有可能以某种方式覆盖共享指针功能?例如,以某种方式添加"onLastRemains"事件?也许我应该遍历unordered_map每一帧的一部分(通过桶)?还有其他方法吗?
我知道,我可以尝试编写自己的引用计数资产实现,但我所有的当前代码都假设资产是共享指针.此外,共享指针非常出色,所以为什么要重新发明轮子呢?
我想知道如何正确使用C++ 11智能指针进行图形表示.
假设您有一个图形结构,其中包含所有顶点的向量.此外,您有一个顶点的结构/类.该顶点包含其所有邻居(邻接列表)的向量.
我的问题是:我应该使用哪种类型的指针/智能指针来表示这个图形?
对于二进制树,我读到,对于父节点,您应该使用原始指针.因为节点不拥有其父节点.二叉树的子节点可以由std :: unique_ptr表示,因为该节点具有子节点的所有权.
但是在图中,多个节点可能具有共同的邻居.那么,我应该使用std :: shared_ptr吗?或者我应该使用原始指针吗?
这是一个后续的问题这个.
我们如何获得std :: unique_ptr或std :: shared_ptr的所有权?
有没有办法保持b活力?
class A{
public:
A() {
b = std::unique_ptr<char[]>(new char[100] { 0 });
}
char* b;
}
void func {
A a;
}
Run Code Online (Sandbox Code Playgroud) 我最近一直在阅读有关std::make_shared功能的内容.据我所知Effective Modern C++,make函数应该是首选,除非:
std::weak_ptr可能比它更长std::shared_ptr,处理大型对象,自定义删除等.所以,我理解std::make_shared只用一次调用就可以在堆及其控制块上分配一个对象.因此,问题是std::shared_ptr在必须释放控制块之前可能不会删除对象.如果我错了,请纠正我,但这是在最后一次std::weak_ptr释放的时候.因此,std::make_shared如果存在std::weak_ptr指向它的活着,则可能不合适.
但这对大多数物体来说仍然是一个问题吗?我们是否需要关注何时为非大型物体发布控制块?可以说,现在内存并不难以获得,所以这只是大型对象和低内存系统的问题吗?
我关注的一点是:如果我设计一个使用的类std::make_shared,并std::weak_ptr在将来使用,我必须返回并用常规替换make函数std::shared_ptr<Class>(new Class()).
有很多事情需要说.首先,我想知道下面的方法是否被认为是设计模式甚至是一种常用技术(这就是为什么我没有提供有关标题的更多信息).如果是这样,那么名字是什么?无论如何,这是我想要实现的缩小版本.由于我需要使用复制,我发现使用std :: shared_ptr是最好避免被释放(删除)的指针.
class Foo
{
public:
Foo() : ptr(nullptr) {}
Foo(const Foo& foo) : ptr(foo.ptr) {}
virtual ~Foo() = default;
void whatever() {
if (ptr)
ptr->whateverHandler();
}
void reset() {
ptr.reset();
}
void resetBar() {
ptr.reset(new Bar);
}
// Other resets here...
protected:
Foo(Foo* foo) : ptr(foo) {}
private:
// Every child class should override this
virtual void whateverHandler() {
throw "whateverHandler cant be called within base class";
}
protected:
std::shared_ptr<Foo> ptr;
};
class Bar : public Foo
{ …Run Code Online (Sandbox Code Playgroud) 我为C ++类实现了C-API,该类使用其他对象的共享指针来访问它们。在我的C-API中,我当然只能获得原始指针。因此,我将C-API中的原始指针“转换”为共享指针,然后将其与C ++类方法一起使用:
method(std::shared_ptr<dataType>(raw-pointer));
Run Code Online (Sandbox Code Playgroud)
现在,我遇到的问题是,在“方法”的末尾,总是会调用共享指针析构函数,并且不幸的是,它杀死了我的原始指针指向的对象(我不想要)。因此,如何防止原始指针被杀死?
我已经尝试过像reset()或swap()这样的共享指针功能,但是它们都没有让我的原始指针走...
method(std::shared_ptr<dataType>(raw-pointer));
Run Code Online (Sandbox Code Playgroud)
预期的结果是,此函数返回后,原始指针e仍指向有效对象。实际上,原始指针然后指向已删除的对象。
shared-ptr ×10
c++ ×9
c++11 ×4
boost ×2
unique-ptr ×2
c-api ×1
graph ×1
inheritance ×1
opengl ×1
pointers ×1
qt ×1
raw-pointer ×1
stl ×1
weak-ptr ×1