是否使用`const std :: shared_ptr< ...>'可变?

时间:2017-06-29 16:24:17

标签: c++ c++11

我试图调整一些预先存在的代码来使用std :: shared_ptr< ...>。这是一个“消息传递系统”。所以基本的背景是:

公共方法:

void writeReport(std::shared_ptr<const ReportBase> pReport) {
  /* This is a public method for writing a report. I might do
     additional stuff in here but end by forwarding to the
     private method. */
  writeReport_(pReport);
}

私人方法:

void writeReport_(std::shared_ptr<const ReportBase> pReport) {
  if( certain conditions )
    processReport_(pReport);

  writeBytes_(serialize(pReport));
}

处理方法:

void processReport_(std::shared_ptr<const ReportBase> pReport) {
  processReportImpl(pReport);

  if( certain other conditions )
    reportDeque_.push_back(pReport);
}

在上面的伪代码中,例如,processReport _(...)可能是在某些条件下想要实际存储记录的唯一方法。其他方法只是对指向的对象的内容感兴趣。那么,如果不是有时需要复制processReport_(...)中的shared_ptr(即&#39;存储&#39;记录),我只需将const ReportBase *传递给我的所有嵌套函数并避免传递值的开销(即使用计数增量)。

所以,我希望传递std::shared_ptr<const ReportBase>&(并且可能&&在适当的地方),但是想要阻止某些流氓嵌套方法实际修改指针所指向的内容。所以我想我想通过const std::shared_ptr<const ReportBase>&来阻止......

...但是,再次,processReport_(...)我有时会想制作一份副本来存储记录。

最后引出了我的问题...

  • 是对std :: shared_ptr可变的使用计数吗?
  • 为什么我可以(或不能)在const std::shared_ptr<...>std::shared_ptr<...>进行复制分配?
  • const是否构成shared_ptr const的整个控制块?或者前导const仅适用于原始指针值?

如果有人想切向回答,请不要过于担心将价值转移到嵌套函数中。或者&#39;我有一个完全不同的方法给你&#39;那么我也有兴趣听到这个。

2 个答案:

答案 0 :(得分:2)

std::shared_ptr存储指向控制块的指针,该指针在堆上分配。毕竟,它必须在shared_ptr的所有副本中共享。因此,当您将const应用于std::shared_ptr时,您只是在指针const。指向的控制块对象保持非常量。想想ControlBlock* const。因此,那里不需要明确的mutable关键字,虽然从逻辑上讲,控制块确实是可变的。

答案 1 :(得分:0)

如果我正确理解你的问题,我会使用像这样的函数

void processReport(const std::shared_ptr<ReportBase> &report) {

    if( certain other condition ) {
        reportDeque_.push_back(report); // will make the copy here
}

使用const std::shared_ptr<ReportBase> &,您不会增加使用次数,因此如果将其添加到矢量,则必须是shared_prt的副本,因此会增加计数,否则计数会保持不变同样的。