Matthew M.
Matthew M.

Reputation: 412

Is use count on `const std::shared_ptr<...>' mutable?

I'm trying to adapt some pre-existing code to make use of std::shared_ptr<...>. It is a `message passing system' so the basic context is:

Public Method:

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);
}

Private Method:

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

  writeBytes_(serialize(pReport));
}

Processing Method:

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

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

Of the above pseudo-code, for example, processReport_(...) might be the only method which, under certain conditions, would want to actually store the record. The other methods are simply interested in the contents of the object pointed to. So, were it not for the need to sometimes copy the shared_ptr in processReport_(...) (i.e., 'store' the record), I would simply pass const ReportBase * to all my nested functions and avoid the overhead of pass-by-value (i.e., use count increments).

So, I want to pass std::shared_ptr<const ReportBase>& (and maybe && where appropriate) but want to preclude some rogue nested method from actually modifying what the pointer points to. So I think I want to pass const std::shared_ptr<const ReportBase>& to prevent that...

... but, again, in processReport_(...) I'll sometimes want to make a copy to store the record.

Which finally leads me to the question(s)...

And if someone wants to answer tangentially 'don't worry so much about passing by value into nested functions' or 'I have a completely different approach for you' then I'd be interested to hear that too.

Upvotes: 3

Views: 1218

Answers (2)

Joseph Artsimovich
Joseph Artsimovich

Reputation: 1519

std::shared_ptr stores a pointer to the control block, which is allocated on the heap. After all, it has to be shared across all copies of that shared_ptr. So, when you apply a const to your std::shared_ptr, you are merely making that pointer const. The control block object being pointed to remains non-const. Think ControlBlock* const. Therefore, there is no need for an explicit mutable keyword there, although logically, the control block is indeed mutable.

Upvotes: 6

Rolf Lussi
Rolf Lussi

Reputation: 615

If I understand your question correctly I would use a function like this

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

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

With the const std::shared_ptr<ReportBase> & you don't increment the use count, so if you add it to the vector it will have to be a copy of the shared_prt and therefore increase the count, if not the count stays the same.

Upvotes: 0

Related Questions