patterncppModerate
Custom class for a borrowed unique_ptr<T>?
Viewed 0 times
borrowedcustomforclassunique_ptr
Problem
In C++11, I tend to have master objects that maintain sole ownership of a collection of some children objects. Let's assume these children objects are non-copyable (for instance,
Other code needs to access these children objects to do some temporary processing, but not keep references, or share ownership over these objects.
As such, my master objects tend to have some sort of a
As an example, let's say I have a
When writing the
-
Return by pointer:
-
Return by reference:
I thought I didn't like either of these (for reasons I explain below), so I came up with the following:
where
To me,
I don't like returning by raw pointer (1.) because I feel that
I don't like returning by reference (2.) because of an additional reason. I am worried that I will write
and invoke a copy when I didn't intend to.
My question: Is
boost::noncopyable).Other code needs to access these children objects to do some temporary processing, but not keep references, or share ownership over these objects.
As such, my master objects tend to have some sort of a
get_child() method.As an example, let's say I have a
Master object like this:class Master {
private:
std::vector> children;
...
public:
??? get_child(int index);
};When writing the
get_child() method, I have 2 obvious options:-
Return by pointer:
Child* get_child(int_index) {
return children[index].get();
}-
Return by reference:
Child& get_child(int index) {
return *(children[index]);
}I thought I didn't like either of these (for reasons I explain below), so I came up with the following:
borrowed_ptr get_child(int index) {
return make_borrowed(children[index].get());
}where
borrowed_ptr is a trivial class wrapping a pointer with no smarts. I provide its implementation at the end of this question.To me,
borrowed_ptr indicates that there exists a unique_ptr someplace, and this borrowed_ptr should be used for a short time, and not be recorded for any circumstance.I don't like returning by raw pointer (1.) because I feel that
Child* doesn't imply that there exists a unique_ptr someplace. Namely, I already have a lot of raw pointers floating around (think handles received from libraries, or my code which is not using smart pointers). I feel borrowed_ptr gives a little more information over a raw pointer.I don't like returning by reference (2.) because of an additional reason. I am worried that I will write
Child child = get_child();and invoke a copy when I didn't intend to.
My question: Is
borrowed_ptr silly? Does it raise red flags with experienced C++ developers? Solution
My question: Is borrowed_ptr silly? Is it a faux pas? Does it feel like a code smell?
It seems a bit overengineered to me (YMMV).
Do you feel I should rather do 1., 2. or something else altogether?
Something else. Consider this alternative:
This has the following advantages:
It seems a bit overengineered to me (YMMV).
Do you feel I should rather do 1., 2. or something else altogether?
Something else. Consider this alternative:
class Master {
private:
std::vector> children;
...
public:
// an observed ptr is not modified in any way by client code
typedef Child const * const ObservedChildPtr;
ObservedChildPtr get_child(int index) const;
};This has the following advantages:
- the semantics for an observed (i.e. not modified) pointer became part of the class' API
- it is explicit and self-explanatory (like your
borrowed_ptr)
- it is minimalistic (you don't define/need the extra class)
- it provides a natural expansion point, in case you actually do need the extra class (see line above) - if you need to expand it, replace
Child const * constwith a class definition.
- client code can be written in terms of
Master::ObservedChildPtr(which you can change later without having to update client code).
Code Snippets
class Master {
private:
std::vector<std::unique_ptr<Child>> children;
...
public:
// an observed ptr is not modified in any way by client code
typedef Child const * const ObservedChildPtr;
ObservedChildPtr get_child(int index) const;
};Context
StackExchange Code Review Q#62270, answer score: 10
Revisions (0)
No revisions yet.