473,394 Members | 1,640 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

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 2730
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Yoon-Soo Lee | last post by:
I am using Visual C++ .NET 2003 and running into some linking error from the following template code. The error messages is error LNK2019: unresolved external symbol "class...
8
by: Douglas | last post by:
**** Post for FREE via your newsreader at post.usenet.com **** Hello, The following code does not compile if line 3 is uncommented "using namespace std". I do not understand it. Could...
10
by: Tony Johansson | last post by:
Hello Experts!! This class template and main works perfectly fine. I have this class template called Handle that has a pointer declared as T* body; As you can see I have a reference counter in...
19
by: jacob navia | last post by:
C++ introduced an interesting feature (among others): operator overloading. The idea is to build a mechanism for the user defining its own number types and the operations to be done with them. ...
3
by: Ondrej Spanel | last post by:
I defined operator = using template member function for a template class. However compiler failed to recognize it is defined and created its own version (which was member-wise copy, and a result...
13
by: kamaraj80 | last post by:
Hi I am using the std:: map as following. typedef struct _SeatRowCols { long nSeatRow; unsigned char ucSeatLetter; }SeatRowCols; typedef struct _NetData
25
by: David Sanders | last post by:
Hi, As part of a simulation program, I have several different model classes, ModelAA, ModelBB, etc., which are all derived from the class BasicModel by inheritance. model to use, for example...
5
by: Gianni Mariani | last post by:
I'm hoping someone can tell me why using member address of works and why using the dot operator does not in the code below. The code below uses the template function resolution mechanism to...
7
by: sidewinder | last post by:
I wish to use a C++ vector class, which I have taken from the book numerical recipes. However due to the nature of the calculations I wish to perform I need to be able to delete the vectors. I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.