Let's say I have a private variable which is a vector of shared_ptr
s to non-const
objects.
Is it possible to write a getter method which only allows read access to the data pointed to by the shared pointers?
I want to be able to use range-based loops for elegance, so I want to avoid writing const_iterators
.
My understanding is that const shared_ptr<T>
makes the pointer itself const
, not T
. I tried to compile shared_ptr<const T>
, but it doesn't compile if T
itself is not declared const
in the class.
In other words, how could I write something like:
#include <iostream>
#include <vector>
#include <memory>
using std::vector;
using std::shared_ptr;
using std::make_shared;
using std::cout;
using std::endl;
class MyClass{
public:
MyClass(int element1, int element2)
{
myVector_.push_back(std::make_shared<int>(element1));
myVector_.push_back(std::make_shared<int>(element2));
}
// I want something like this, but doesn't compile
// const vector<shared_ptr<const int>> readMyVector() const {return myVector_;}
const vector<shared_ptr<int>> readMyVector() const {return myVector_;}
private:
// Should NOT be <const int>, the class should be able to modify its elements
vector<shared_ptr<int>> myVector_;
};
int main(){
auto testobject = MyClass(1,2);
for (auto my_protected_data : testobject.readMyVector()){
cout<<(*my_protected_data)<<endl;
(*my_protected_data) = 25;
cout<<(*my_protected_data)<<endl; // Should not happen
}
return 0;
}
The correct type to return is std::vector<std::shared_ptr<const int>>
, but you'll have to make that vector by hand. std::shared_ptr<T>
is convertible to std::shared_ptr<const T>
, but the problem is that std::vector<T>
isn't implicitly convertible to std::vector<U>
simply because T
is convertible to U
.
The easiest way is to construct a vector from your internal vector's begin
and end
iterators.
vector<shared_ptr<const int>> readMyVector() const
{
return{ myVector_.begin(), myVector_.end() };
}
Note that adding const
to the return type of a function that returns by value is rarely useful.
You should also ask yourself rather it's worth it to copy all of those std::shared_ptr
. You may want to consider simply returning a vector of int
.