【发布时间】:2008-12-12 16:47:15
【问题描述】:
我很好奇,因为我开始采用更多的 boost 习语以及似乎是最佳实践的最佳实践那些没有接触过“现代 C++”的人?
【问题讨论】:
标签: c++ boost smart-pointers
我很好奇,因为我开始采用更多的 boost 习语以及似乎是最佳实践的最佳实践那些没有接触过“现代 C++”的人?
【问题讨论】:
标签: c++ boost smart-pointers
我几乎不使用shared_ptr,因为我通常避免共享所有权。因此,我使用boost::scoped_ptr 之类的东西来“拥有”一个对象,但对它的所有其他引用都将是原始指针。示例:
boost::scoped_ptr<SomeType> my_object(new SomeType);
some_function(my_object.get());
但是some_function 会处理一个原始指针:
void some_function(SomeType* some_obj)
{
assert (some_obj);
some_obj->whatever();
}
【讨论】:
我脑子里只有几个:
这里的共同点是“任何情况下,您需要将一块内存视为您拥有分配控制权的资源以外的东西”。
【讨论】:
这些天来,我几乎放弃了对原始指针的所有使用。我什至开始在我们的代码库中查找使用原始指针的地方,并将它们切换为智能指针变体。通过这个简单的操作,我能够删除多少代码,真是令人惊讶。在原始 C++ 指针的生命周期管理上浪费了太多代码。
我不使用指针的唯一地方是用于与我无法控制的其他代码库的几个互操作场景。
【讨论】:
我发现“现代”C++ 和旧* 的主要区别在于谨慎使用类不变量和封装。组织良好的代码自然倾向于有更少的指针飞来飞去。在 shared_ptrs 中游泳时,我几乎和在新闻和删除中一样紧张。
我期待 C++0x 中的 unique_ptr。我认为这将消除仍然在野外漫游的少数(智能)指针。
*不幸的是仍然很常见
【讨论】:
当然,在处理遗留库或 API 时,您需要传递一个原始指针,尽管您可能只是暂时从智能指针中提取它。
事实上,将原始指针传递给函数总是安全的,只要函数不尝试将指针的副本保留在全局变量或成员变量中,或者尝试删除它。有了这些限制,函数就不会影响对象的生命周期,智能指针的唯一原因是管理对象的生命周期。
【讨论】:
我仍然在资源敏感代码或其他需要占用空间很小的代码中使用常规指针,例如某些异常,我不能假设任何数据都是有效的,并且还必须假设我的内存也快用完了。
托管内存几乎总是优于原始内存,因为这意味着您不必在正确的位置处理它,但仍然可以很好地控制指针的构造和销毁点。
哦,还有另一个地方可以使用原始指针:
boost::shared_ptr<int> ptr(new int);
【讨论】:
我仍然在具有内存映射 IO 的设备上使用原始指针,例如嵌入式系统,在这些设备上拥有智能指针并没有真正意义,因为您永远不需要或无法delete 它。
【讨论】:
如果你有循环数据结构,例如,A 指向 B,B 指向 A,你不能天真地为 A 和 B 使用智能指针,因为那样对象只会被释放额外的工作。要释放内存,您必须手动清除智能指针,这与删除智能指针一样糟糕。
您可能会认为这种情况并不经常发生,但假设您的 Parent 对象具有指向一堆 Child 对象的智能指针。在某个地方,有人需要查找父级的子级,因此他们向子级添加了一个智能指针成员,该成员指向父级。默默地,内存不再被释放。
需要一些小心。智能指针不等同于垃圾回收。
【讨论】:
我正在编写必须与 Objective C 共存的 C++(使用 Objective C++ 进行桥接)。 因为声明为 Objective C++ 类的一部分的 C++ 对象没有调用构造函数或析构函数,所以不能真正将它们保存在智能指针中。
所以我倾向于使用原始指针,尽管通常使用 boost::intrustive_ptr 和内部引用计数。
【讨论】:
我不会这样做,但您需要原始指针来实现,例如,链表或图表。但是使用std::list<> 或boost::graph<> 会更聪明。
【讨论】: