Reputation: 2992
I am creating a pointer class, but I can't figure out how to return the value (address of the object pointed to) of the raw pointer handled by my class. My class is like this.
template<typename T>
class Ptr {
public:
Ptr(T t) :p{&t} { }
T* operator->() { return p; }
T& operator*() { return *p; }
T& operator[](int i) { return p[i]; }
private:
T* p;
};
If I will do:
int x = 42;
Ptr<int> y = x;
std::cout << y; //should print the address (y.p).
I absolutely don't know what operator to overload so if I use "y" in any expression it will return the address of the object pointed to, just like what a raw pointer does. What should I do?
Upvotes: 0
Views: 91
Reputation: 171127
First off, your code has a bug. Your constructor is taking t
by value, which means that p
will store the address of the temporary t
which will die at constructor exit (and the pointer will become dangling). You probably want this:
Ptr(T &t) : p{&t} {}
Even so, this means your pointer wrapper will be initialised by objects and not by pointers, which looks counter-intuitive. I'd change the constructor to accept a T*
.
Second, you're asking how to get the "address of the raw pointer," but I assume you really want the "address stored in the raw pointer."
With this out of the way, let's turn to your question. There are several ways you can approach this.
One is to give your class an implicit conversion to T*
, like this:
operator T* () const
{ return p; }
That way, an implicit conversion from Ptr<T>
to T*
will exist and the compiler will use it wherever necessary, but that may be a bit more than you want.
A more restricted version is to make the conversion explicit:
explicit operator T* () const
{ return p; }
Now you have to cast to the pointer explicitly:
std::cout << static_cast<int*>(y);
You can follow the pattern used by std
smart pointers and provide a get()
function:
T* get() const
{ return p; }
std::cout << y.get();
Finally, if you only want this functionality for streaming, you can just overload operator<<
for your class:
template <class T, class Char, class Traits>
std::basic_ostream<Char, Traits>& operator<< (std::basic_ostream<Char, Traits> &stream, const Ptr<T> &ptr)
{
return stream << ptr.operator->(); // or ptr.get(), if you implement it
}
Upvotes: 4
Reputation: 66371
You should overload operator T*()
.
Note that the pointer you're storing is a pointer to the parameter and becomes invalid as soon as the constructor returns, so dereferencing it anywhere causes your program to be undefined.
You probably want
Ptr(T* t) : p{t} { }
and
Ptr<int> y = &x;
Upvotes: 2