我有一个包含对象指针向量的类。我在该类中有一个GetObject(..)函数,它通过向量查找,找到所需的对象,并返回指向它的指针。但是,如果该类的用户对该返回的指针执行了delete(),则我的程序将崩溃,因为该向量仍然具有指向该对象的指针,该对象现在是无效的。因此,在我的GetObject()类中,我可以返回一个const指针,但这并不能解决问题,因为您仍然可以删除该对象。该对象是可变的,所以我不能返回指向const对象的指针。我想我可以通过返回对象的引用来阻止删除但是如果有错误我的函数返回NULL。我想我可以通过参数传回对象引用,然后像这样返回错误号
//-1 on object on found. 0 for success. Object is passed back in
// the function parameter result.
int MyObject::GetObject(int object_id, Item& result)
这是针对这种情况的最佳解决方案吗?
答案 0 :(得分:6)
解决此问题的最佳方法是使用共享所有权智能指针,如shared_ptr
,您可以在Boost,C ++ TR1和C ++ 0x中找到它。
智能指针是一个容器,可以为您管理动态分配的对象的生命周期。完成使用后,它负责delete
对象。
使用共享所有权智能指针,您可以拥有多个智能指针,这些指针都共享动态分配对象的所有权。保留引用计数以跟踪有多少智能指针拥有对象的所有权,并且当最后拥有的智能指针被销毁时,动态分配的对象为delete
d。
在C ++中手动管理资源非常困难,并且编写看起来正确且大部分时间正常工作但仍然不正确的代码非常容易。通过使用智能指针和其他资源拥有容器(如标准库容器),您不再需要手动管理资源。当您的所有资源管理都是自动的时,编写正确的代码要容易得多。
C ++中的自动资源管理是使用名为Resource Acquisition is Initialization (RAII)的设计模式完成的,这可以说是您作为C ++程序员应该熟悉的最重要的设计模式。
答案 1 :(得分:2)
您的代码中的任何人也可以尝试取消引用NULL。你会阻止他们这样做吗?如果您的容器拥有该对象,并且您明确了这一点(返回一个原始指针通常很清楚或在文档中提及),那么任何删除它的人,结果都是他们自己的错。保证删除对象的唯一方法是防止用户获取本机引用或指针 - 在这种情况下,他们无法访问该对象。
答案 2 :(得分:2)
谁是您班级的客户?如果他们不是你的致命敌人,你可以很好地问他们不要删除对象。否则,“他们”总会有办法搞砸你。
好的,一种可能的解决方案是将析构函数设为私有。这将阻止每个人删除该对象。但是,对象必须以某种方式删除自身(delete this
),可能通过一些名为DeletObjectButDontBlameMeIfAppCrashes
的函数。如果所有者是其他类,那么您可以将析构函数设置为protected和owner类作为此类的朋友。
答案 3 :(得分:1)
您应该返回对该对象的引用。当没有找到对象时,有两种方法可以处理这种情况。
首先,您可以使用Null Object Pattern来为该案例实现特殊值。这可能对你的情况没有意义。
另一种方法是将其拆分为两个方法,一个可用于检查是否存在适当的元素,另一个用于检索它。
许多STL容器或算法通过返回一个过去的迭代器或者empty() returns false
作为调用front
或{{1}之类的方法的先决条件来实现这两者}}
答案 4 :(得分:0)
如果可以使用boost库,smart pointers可用于确保指针保持有效。实质上,对智能指针的每次引用都会将其“使用次数”增加1.当在引用上调用reset
函数时,引用会消失,使用计数器会递减。只要某个对象仍然保持智能指针,该引用将是有效的。请注意,其他类将能够更改其指向的内容,但无法删除它。
(我的描述主要涉及智能指针 - 不同类型的指针略有不同,但总体思路保持不变)。