Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const correctness of a member function returning a shared_ptr<>

if I have the class

class foo {
   private:
      std::shared_ptr<char> m_data;
   public:
      std::shared_ptr<const char> GetData()
      { return m_data;}
} 

I believe that std::shared_ptr< T > should cast to std::shared_ptr< const T > and share the same object, but what's the const correctness on the function?

IE is this valid?

std::shared_ptr<const char> GetData() const;
like image 802
Sparky Avatar asked Mar 18 '14 10:03

Sparky


2 Answers

  • Does the function modify the internal state of the object? No. *

  • Does the function give its caller (or other outside environment) modification access to the internal state of the object? No.

This means it's safe to mark it as const.

* Note: @Yakk correctly pointed out in the comments that for some definition of "internal state," the function does indeed modify it, because it increments the reference counter on the char owned by the shared pointer m_data. You have to decide for yourself whether that constitutes a non-const operation; strictly by the rules of the language, it does not (because it modifies something pointed to by the shared_ptr, not the shared_ptr itself). But since you store a shared_ptr in the first place, I assume you're fine with sharing ownership, so doing it shouldn't be viewed as a modification.

like image 52
Angew is no longer proud of SO Avatar answered Oct 17 '22 06:10

Angew is no longer proud of SO


You should be very careful with code like that. In the state your code is in at the moment, everything will be safe, because you're only wrapping a shared_ptr and nobody can modify the contents because they are private. However, if you extend your code there is a subtle but severe pitfall that can be hard to debug: If you add functions that modify the data to which the shared_ptr points, then code that already owns a shared_ptr to a const char from your GetData() function will see the modified data and not a copy of the data.

In C++ the keyword const really means read-only and not immutable as many think when they first learn it. A way to make your code future-proof would be to use std::shared_ptr<char> as data type for your data member m_data. If that is not appropriate for your requirements of your code, consider to just return a complete copy of your data when the function GetData() is called. Implementing copy-on-write may be necessary, if you have bad performance constraints, but unless you're sure of these performance penalties avoid copy-on-write, because it's tricky because of the reasons above.

like image 2
Ralph Tandetzky Avatar answered Oct 17 '22 08:10

Ralph Tandetzky