In addition to pointers, C++ also provides references that behave similarly. In addition to these built-in types, it also gives the option to construct custom types that mimic this behavior.
Take these two custom types:
class Ptr
{
private:
int inner_;
public:
int& operator*() { return inner_; }
const int& operator*() const { return inner_; }
};
class Ref
{
private:
int inner_;
public:
operator int&() { return inner_; }
operator const int&() const { return inner_; }
};
These two types are used in different ways:
void f(const int& x);
auto r = Ref{};
auto p = Ptr{};
f(r);
f(*p);
These two are not equivalent but serve largely the same purpose. In the C++ standard library, example types are:
- pointer behavior:
std::optional,std::unique_ptr - reference behavior:
std::reference_wrapper,std::atomic
In case we are designing a custom data type for which both pointer behavior and reference behavior are reasonable, which one should be chosen?
C++ doesn't allow overloading
operator.. So, whatever you do it is not possible to achieveref.foo()syntax in a generic way.std::reference_wrapper, for instance, usesref.get().foo()syntax, which is rather convoluted.Aside from that, implicit conversions you have in your examples are error prone and generally not desirable.
Considering these, I would design my custom class to act like a pointer, because that is fully achievable with the current language rules.