如何防止删除 QSharedPointer 管理的指针
我在 Qt 应用程序中遇到一些间歇性分段错误。我认为这个问题与我们对 QSharedPointer 的(错误)使用有关。 Qt 文档指出:
QSharedPointer::QSharedPointer ( T * ptr ) : 创建一个指向 ptr 的 QSharedPointer。指针 ptr 从此 QSharedPointer 管理,并且不得传递给另一个 QSharedPointer 对象或在此对象之外删除。
我认为我们都在做不能... :/
有没有一种 OOP 方法来强制 QSharedPointer
管理的指针不能被删除或传递给另一个 QSharedPointer?
最好的解决方案是出现编译器错误。
I have some intermittent segmentation faults in a Qt application. I think the problem is related to our (bad) use of QSharedPointer
. The Qt Documentation states :
QSharedPointer::QSharedPointer ( T * ptr ) :
Creates a QSharedPointer that points to ptr. The pointer ptr becomes managed by this QSharedPointer and must not be passed to another QSharedPointer object or deleted outside this object.
I think we are doing both must not... :/
Is there a OOP way to enforce that the pointer managed by QSharedPointer
cannot be deleted or passed to another QSharedPointer
?
The best solution will be to have a compiler error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正常的模式是将 new 语句放在智能指针的构造函数中,如下所示:
这样您就永远不会引用裸指针本身。
如果您重构代码,使所有新运算符都位于这样的行中,那么所有问题都将得到解决。
The normal pattern is to put the
new
statement inside the smart pointer's constructor, like this:That way you never have a reference to the naked pointer itself.
If you refactor your code so that all new operator are in lines like these, all your problems will be solved.
好吧,一种 OOP 式的方法是将原始指针创建为包装类中的私有成员,并且仅通过作用于共享指针的方法对指针执行操作。虽然有点傻,不是吗?
或者,您可以使带有原始指针的类成为其他类的基类,并使原始指针成为该类中的私有成员。在这方面,您或多或少创建了一个不执行任何操作的抽象类。相反,您的派生类必须完成所有工作,并且由于它们无法访问原始指针,编译将失败...但这并不能阻止某人从共享指针中复制原始指针值。
最后,我认为最好的策略是手动更改所有相关函数以使用共享指针或原始指针。您可以安全地将一个共享指针复制到另一个共享指针,那么为什么不这样做呢?
编辑:
我可能会补充一点,无论您是否使用共享指针,听起来您都遇到了所有权问题。如果一个指针是在一个作用域中创建的,则应该在该作用域中将其删除,除非按合同方式传递给它的函数取得了该指针的所有权。在这种情况下使用共享指针最终只会导致不同的错误。听起来您的设计问题不仅仅是共享指针。
Well, an OOP-esque way would be to create the raw pointer as a private member in a wrapper class, and only perform actions on the pointer through methods that act on the shared pointer. kind of silly though, isn't it?
Or you could make your class with the raw pointer a base class to your other classes and make the raw pointer a private member in the class. In this regard, you're more or less creating an abstract class that does nothing. Your derivative classes must instead do all the work, and since they can't access the raw pointer, compilation will fail... this doesn't stop someone from just copying the raw pointer value out of the shared pointer, though.
In the end, I think your best policy is to manuall change all of the functions in question to use either a shared pointer or else a raw pointer. You can copy one shared pointer to another safely, so why no just go that way?
Edit:
I might add that regardless of whether or not you're using shared pointers, it sounds like you're having ownership issues. If a pointer was created in one scope, it should be deleted in that scope, unless the function that it is passed to contractually takes ownership of the pointer. Using a shared pointer in this scenario will only caused different bugs, eventually. It sounds like you have design issues deeper than just the sharing of pointers.
我不熟悉共享指针的特定 Qt 实现,但作为一般准则:尝试将原始指针与托管指针混合通常会以血腥告终。一旦您“信任”共享指针实现获得动态分配数据的所有权,您在任何情况下都不应该尝试自己管理对象生存期(例如通过删除提供的指针)。
有没有一种OOP方法来强制QSharedPointer管理的指针不能被删除?
我想你可以想象一些奇怪的技术,其中指向的类型将有一个私有析构函数并将QSharedPointer声明为友元(这将有效地防止任何“外部删除”编译),但我不打赌可以从中得到任何好处(并注意,它将使您的类型绝对无法使用,除非进行更新并转移到 QSharedPointer)。
是否有 OOP 方法来强制 QSharedPointer 管理的指针不能传递给另一个 QSharedPointer?
我想不出任何方法,这就是为什么您应该避免在原始指针被操作后对其进行操作的另一个原因所有权已转移到 QSharedPointer。
I'm not familiar with the particular Qt implementation of a shared pointer, but as a general guideline : attempting to mix raw pointers with managed pointers usually ends in blood. Once you 'trust' a shared pointer implementation in taking ownership of your dynamically allocated data, you should under no circumstances try to manage the object lifetime yourself (for example by deleting the provided pointer).
Is there a OOP way to enforce that the pointer managed by QSharedPointer cannot be deleted ?
I guess you could imagine some weird technique where the pointed type would have a private destructor and declare QSharedPointer as friend (which would effectively prevent any 'outside deletion' from compiling), but I wouldn't bet that anything good can come out of this (and note that it will make your type absolutely unusable unless new'ed and transfered to a QSharedPointer).
Is there a OOP way to enforce that the pointer managed by QSharedPointer cannot be passed to another QSharedPointer?
I can't think of any, and that is another reason why you should avoid manipulating the raw pointer once it's ownership has been transferred to a QSharedPointer.
检查代码中所有 .data() 的使用情况,并确保它们返回的内容既不会被存储也不会被删除。我不认为硬编译器错误是好的,因为有时可以传递原始指针,例如传递给不存储也不删除传递的指针的函数。 (特别是在使用第 3 方代码时,您不能总是更改所有内容以使用共享指针,并且通常您希望它能够与原始指针和共享指针一起使用)。
人们可以将 QSharedPointer::data() 标记为已弃用(通过修补 Qt),以获得编译时警告。
Check your code for all .data() usage and make sure what they return is neither stored nor deleted. I don't think a hard compiler error would be good, because sometimes it's okay to pass the raw pointer, e.g. to a function that doesn't store nor delete passed pointers. (Especially when using 3rd-party code, you cannot always change everything to use shared pointers, and often you want it to work with both, raw and shared ptrs).
One could mark QSharedPointer::data() as deprecated (by patching Qt), to get a compile time warning.