C++: -> operator overloading: Handle const / nonconst access differently
I'm building a reference counting system and have defined a prototype template class which represents all references to objects that will be used.
The point where I am stuck is that I have to differentiate between const and non const access to those objects through a reference. If the access is const (read-only, or called method of underlying object is flagged const), everything is okay - however if it's not - a copy of the object might have to be created first.
A simplified version of my reference class:
template< class T >
class CRef
{
protected:
T* ptr;
public:
T* const* oper开发者_StackOverflow中文版ator ->() const { return ptr; };
T* operator ->() { printf( "Non-const access!" ); return ptr; };
};
The problem is, that only the non-const -> operator overload function gets called, even when accessing const functions of the underlying object type.
- How do I get the constant dereferencing overloading function to get called properly?
The const one is called on const objects. If you want the const -> called, cast the object reference you have to a const or provide a way to get a const version of the object.
const
/ non-const cannot, in principle, be used to differentiate between read and write access.
You’re out of luck here. The only way to accomplish this is via a proxy object that is returned by operator ->
and that handles reading via an implicit conversion:
The returned proxy defines an operator T
(implicit conversion) that is invoked when it is assigned to another object, and an operator =(T const&)
when something is assigned to it.
template <typename T>
class CRef {
…
CRefElementProxy<T> operator ->() const { return CRefElementProxy<T>(this); };
friend CRefElementProxy;
};
template <typename T>
class CRefElementProxy {
operator T const*() const { return parent->ptr; }
CRefElementProxy operator =(T const* value) {
printf("Non-const access!");
return parent->ptr;
}
};
That’s just a pseudo-codey draft. The real version looks a bit more complex.
Once the pointer has been returned then there is no way to know what is done with it.
精彩评论