12

我很好奇,因为我开始采用更多的 boost 习语以及似乎是最佳实践的最佳实践'还没有被介绍给“现代 C++”?

4

10 回答 10

7

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();
}
于 2008-12-12T17:17:43.203 回答
6

只是我的头顶上的一些:

  • 在内存映射文件中导航。
  • 您必须过度分配的 Windows API 调用(如 LPBITMAPINFOHEADER)。
  • 您在任意内存(VirtualQuery() 等)中四处游荡的任何代码。
  • 几乎任何时候你都在指针上使用 reinterpret_cast<> 。
  • 任何时候使用placement-new。

这里的共同点是“任何情况下,您需要将一块内存视为您拥有分配控制权的资源以外的东西”。

于 2008-12-17T22:56:13.420 回答
4

这些天来,我几乎放弃了对原始指针的所有使用。我什至开始在我们的代码库中查找使用原始指针的地方,并将它们切换为智能指针变体。通过这个简单的操作,我能够删除多少代码,真是令人惊讶。在原始 C++ 指针的生命周期管理上浪费了太多代码。

我不使用指针的唯一地方是与我无法控制的其他代码库的几个互操作场景。

于 2008-12-12T16:59:11.320 回答
4

我发现“现代” C++ 和旧* 东西之间的主要区别在于谨慎使用类不变量和封装。组织良好的代码自然倾向于有更少的指针飞来飞去。在 shared_ptrs 中游泳时,我几乎和在新闻和删除中一样紧张。

我很期待unique_ptr在 C++0x 中。我认为这将清理仍然在野外漫游的少数(智能)指针。

*不幸的是仍然很常见

于 2008-12-12T17:27:29.593 回答
4

当然,任何时候处理遗留库或 API 时都需要传递原始指针,尽管您可能只是暂时从智能指针中提取它。

事实上,将原始指针传递给函数总是安全的,只要函数不尝试将指针的副本保留在全局变量或成员变量中,或者尝试删除它。有了这些限制,函数就不能影响对象的生命周期,智能指针的唯一原因是管理对象的生命周期。

于 2008-12-12T17:41:23.483 回答
2

我仍然在资源敏感代码或其他需要占用空间很小的代码中使用常规指针,例如某些异常,我不能假设任何数据都是有效的,并且还必须假设我的内存也快用完了。

托管内存几乎总是优于原始内存,因为这意味着您不必在正确的位置处理删除它,但仍然可以很好地控制指针的构造和销毁点。

哦,还有另一个地方可以使用原始指针:

boost::shared_ptr<int> ptr(new int);
于 2008-12-12T16:59:43.737 回答
2

我仍然在具有内存映射 IO 的设备(例如嵌入式系统)上使用原始指针,在这些设备中拥有智能指针并没有真正意义,因为您永远不需要或无法使用delete它。

于 2008-12-12T17:18:51.983 回答
1

如果你有循环数据结构,例如,A 指向 B,B 指向 A,你不能天真地为 A 和 B 使用智能指针,因为那样对象只会被释放额外的工作。要释放内存,您必须手动清除智能指针,这与删除智能指针一样糟糕。

您可能会认为这种情况不会经常发生,但假设您的 Parent 对象具有指向一堆 Child 对象的智能指针。在某个地方,有人需要查找父级的子级,因此他们向子级添加了一个智能指针成员,该成员指向父级。默默地,内存不再被释放。

需要一些照顾。智能指针不等同于垃圾回收。

于 2008-12-12T17:02:43.683 回答
1

我正在编写必须与 Objective C 共存的 C++(使用 Objective C++ 进行桥接)。因为声明为 Objective C++ 类的一部分的 C++ 对象没有调用构造函数或析构函数,所以您不能真正将它们保存在智能指针中。

所以我倾向于使用原始指针,尽管通常使用 boost::intrustive_ptr 和内部引用计数。

于 2008-12-12T17:54:20.210 回答
0

并不是说我会这样做,但您需要原始指针来实现,例如,链表或图表。std::list<>但是使用or会更聪明boost::graph<>

于 2008-12-12T21:00:38.010 回答