470,596 Members | 1,681 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,596 developers. It's quick & easy.

using operator overloding with template

Hello Experts!

I have one class template here called Handle and one concrete class called
Point.
At the bottom is the main program and the class template definitions for
Handle.
This program works fine but there are two thing that I
don't understand completely and that is these two operator that exist in the
class template Handle.
Body* operator->()
{ return bridge; }

Body& operator*()
{ return *bridge; }

How can it be possible to use this line cout << hp1->getX() << endl;
when hp1 is not a pointer. I instansiate this hp1 in main that exist at the
bottom.

And the same here how can it be possible to dereference object hp1
when hp1 is not a pointer.
Point b = *hp1;
The second question is the operator->() returns a pointer so the statement
hp1-> will return a pointer to
Body by calling the operator->() how is it then possible to call getX(). If
I substitute this it's look like.
hp1.operator->()getX
Note you have no -> before getX. Because this program works there must exist
a -> before getX but I can't understand how these two characters -> can be
placed there.

********************
class definition for Handle
********************
template <typename Body>
class Handle
{
public:
explicit Handle(Body* b = 0) : bridge(b), counter(new int(1))
{ }

Handle(const Handle<Body>& h) :counter(h.counter)
{ (*counter)++; }

~Handle()
{
if (--(*counter) == 0)
{
delete counter;
delete bridge;
}
}

Handle& operator=(const Handle<Body>& rhs)
{
if (this == &rhs || bridge == rhs.bridge)
return *this;

if (--(*counter) == 0)
{
delete counter;
delete bridge;
}

bridge = rhs.bridge;
counter = rhs.counter;
(*counter)++;
return *this;
}

Body* operator->()
{ return bridge; }

Body& operator*()
{ return *bridge; }

private:
Body* bridge;
int* counter;
};

class Point
{
public:
Point(double d1=0, double d2=0) : x(d1), y(d2) {}
virtual ~Point() {}

double getX()
{ return x; }

double getY()
{ return y; }

void setX(double d)
{ x = d; }

void setY(double d)
{ y = d; }
private:
double x;
double y;
};

#include <iostream>
#include "handle.h"
using namespace std;

int main()
{
Handle<Point> hp1(new Point(1,2));
cout << hp1->getX() << endl;
Point b = *hp1;

Handle<Point> hp2(hp1);
Handle<Point> hp3(new Point(3,4));
hp3 = hp2;
cout << hp2->getY() << " " << hp3->getY() << endl;
return 0;
}

Many thanks

//Tony
Aug 17 '05 #1
2 2605
Tony Johansson wrote:
I have one class template here called Handle and one concrete class called
Point.
At the bottom is the main program and the class template definitions for
Handle.
This program works fine but there are two thing that I
don't understand completely and that is these two operator that exist in the
class template Handle.
Body* operator->()
{ return bridge; }

Body& operator*()
{ return *bridge; }

How can it be possible to use this line cout << hp1->getX() << endl;
when hp1 is not a pointer. I instansiate this hp1 in main that exist at the
bottom.

And the same here how can it be possible to dereference object hp1
when hp1 is not a pointer.
Point b = *hp1;
[...]


That's just the convention the language has. If a type overloads the
operator ->, then the expression object_of_that_type->something resolves
into

(object_of_that_type.operator->)->something

As to the dereference operator, think of it as if it were the unary +,
there is no difference in syntax.

V

Aug 17 '05 #2

Tony Johansson wrote:
Hello Experts!

I have one class template here called Handle and one concrete class called
Point.
At the bottom is the main program and the class template definitions for
Handle.
This program works fine but there are two thing that I
don't understand completely and that is these two operator that exist in the
class template Handle.
Body* operator->()
{ return bridge; }

Body& operator*()
{ return *bridge; }

How can it be possible to use this line cout << hp1->getX() << endl;
when hp1 is not a pointer. I instansiate this hp1 in main that exist at the
bottom. it is using the operator->() method you provided. Note that you didn't
override the -> operator for pointers to Handle objects but for objects
of type Handle. One cannot override the -> operator for pointers to
objects.

And the same here how can it be possible to dereference object hp1
when hp1 is not a pointer.
Point b = *hp1; same goes here. You override operators for objects not for pointers to
objects


The second question is the operator->() returns a pointer so the statement
hp1-> will return a pointer to
Body by calling the operator->() how is it then possible to call getX(). If
I substitute this it's look like.
hp1.operator->()getX
Note you have no -> before getX. Because this program works there must exist
a -> before getX but I can't understand how these two characters -> can be
placed there.
operator->() is special. The compiler will insert that arrow (->)
before getX so the statement will look like

hp1.operator->()->getX

As I said, the operator is special. It applies itself recursively. That
is, if the operator->() returns an object, then the operator->() will
be called for that object and so on until the return value is a
pointer. Then, the regular operator -> is applied to that pointer. See
the code below:

#include <iostream>

// provides the getX method
class A
{
int m_x;
public:
int getX()
{
return m_x;
}

A(int val) : m_x(val)
{
}
};

class B
{
A m_a;
public:
B(int val) : m_a(val)
{
}

A* operator->()
{
return &m_a;
}
};

class C
{
B m_b;
public:
C(int val) : m_b(val)
{
}

// note that it returns an object (not a pointer)
B operator->()
{
return m_b;
}
};

int main()
{
C c(100);
// check out the statement below
std::cout << c->getX() << std::endl;

return 0;
} Many thanks

//Tony


dan

Aug 17 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Douglas | last post: by
10 posts views Thread by Tony Johansson | last post: by
19 posts views Thread by jacob navia | last post: by
3 posts views Thread by Ondrej Spanel | last post: by
13 posts views Thread by kamaraj80 | last post: by
25 posts views Thread by David Sanders | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.