4

我的团队对于特定上下文的指针容器使用存在一些分歧。请考虑:

int main() {
   // Top level. This is an important fact to the context
   // i.e. that the following instance is at this level
   // so that its members are essentially at program scope.
   MainClass mainClass;
   mainClass.run();
}

// A instance of a class derived from Buffer does something very complex
// (it has various handles to resources/allocated memory) so that you would
// never want to copy an instance.
class Buffer;

class MainClass {

   #make_decision_here_based_on_stack_overflow_responses
   shared_ptr<Buffer> buffer; // 1
   scoped_ptr<Buffer> buffer; // 2
   #end_decision

   MainClass() {
       // non-trivial initialisation of buffer with any of a number of derived classes:
       buffer.reset( ... )
   }    

   void run() {
       #make_decision_here_based_on_stack_overflow_responses
       SomeSubservientClass sub(*buffer);      // a
       SomeSubservientClass sub(buffer.get()); // b
       SomeSubservientClass sub(buffer);       // c
       #end_decision
       sub.do_stuff()
   }
};

(我希望你能理解这里实际上并不存在的特殊预处理器代码,但如果它存在就好了:)

我们目前拥有的代码处于状态“1b”(shared_ptr 成员,传递裸 ptr),但我们认为这不是应该的样子。我很想知道任何人乍一看认为是最自然/合理和最安全的事情和理由。或者,如果有人想建议“3”或“d”。我自己有一个意见,但还不想分享。

4

1 回答 1

7

智能指针的选择是所有权策略的选择。你必须问自己这个问题:

  • 是实例MainClass的唯一所有者吗?还是存储在其中的实例比对象寿命更长Buffer有意义?(或者如果成为更大系统的一个组件并失去其应用程序生命周期状态是否有意义?)BufferMainClassMainClassMainClass

如果答案是有意义的,请使用共享指针。如果答案是唯一所有者/没有意义,请使用表达唯一所有权的东西 - scoped_ptr(或std::unique_ptr,如果可用)。

如果您最终拥有唯一所有权,请使用选项“a”来传递对象。如果空指针是它的有效输入,则函数应该只接受指针参数。

如果您最终拥有共享所有权,则有两种可能的情况。要将缓冲区传递到共享所有权的地方,请传递shared_ptr自身。要将其传递到仅观察/修改的地方,请如上所述使用“a”。

于 2013-07-30T16:30:55.567 回答