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;
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With