I'm trying to design an API for an object manager that registers and retrieves different related objects. When I want to retrieve an object, I can query it by its object id. I'm wondering if I should be returning a smart pointer or a reference in this case. Here's code to fully illustrate the design and some associated scenarios:
// relevant classes portions:
class ViewManager
{
std::unordered_map<int, std::shared_ptr<cView>> mViews;
cView & getView(const uint32_t v){ return *mViews[v]; }
std::shared_ptr<cView> getViewPtr(const uint32_t v){ return mViews[v]; }
}
class cView;
int main()
{
// usage
ViewManager &viewman = ViewManager::getManager(context);
viewman.getView(static_hash("window1")).doFirstThing(arg1, arg2);
viewman.getView(static_hash("window1")).doSecondThing(something, arg1);
viewman.getView(static_hash("window1")).doThirdThing(x,y,z);
// the below function takes a std::shared_ptr<cView>
someOtherFunctionSetView( viewman.getViewPtr(static_hash("window1"));
}
My first question is, should I have getView() return the reference as it is now, or should it return the smart_ptr? In the reference's case, I feel it's more convenient to call .doFirstThing(), .doSecondThing(), versus writing out -> to do this. And the -> implies it might be null, so we should check first before using it.
But then when I need to pass the smart pointer to a function that requires it, I need to create a different getter, getViewPtr() in this case.
What are some pros and cons of doing only smart pointers, or doing it this way, or are there any other better ways to make usage of the API as clean as possible?
Another related question I have is, is there a better way of cleanly using this API instead of writing getView() for each line when calling those functions? I actually prefer it this way as it is big and bold that I'm manipulating the same variable over and over. Alternatively, I could write a cView &ref = getView() and use that. Although it would be more efficient, when writing blocks of these for multiple views, it breaks up the flow enough that it becomes harder to read I think? I've also seen APIs that just do one getView() and string .doSomething().doSomethingElse().doSomethingElse(), which seems very foreign to me.
Are there any flaws to any of the designs aside from stylistic choice. As for stylistic choice is there an objective perspective of what would make one style more readable or maintainable vs. another style? Thank you in advance.