473,378 Members | 1,539 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,378 software developers and data experts.

why does this work ? (operator overloading)

PKH
This is a part of an autopointer template i'm using. I originally had a
Get() member that returned the pointer, but thought it would nice to be able
to use the -> operator.
The question is why does the following line work, and call
cAP.m_pcPointer->Testing() ?

cAP->Testing(); // ???

cAP-> returns a CTest*, so it looks to me like the line reads
cAP.m_pcPointer <whitespace> Testing(), but it actually does
cAP.m_pcPointer->Testing(). I thought maybe it would be called with a bad
this-pointer, but it's the this-pointer is correct inside Testing(). What am
I not seeing here ?
template <class T> class TAutoPointer
{
private:
T
m_pcPointer;

public:
TAutoPointer(T t) : m_pcPointer(t) {}
~TAutoPointer(){if (m_pcPointer) delete m_pcPointer;}

T& operator -> ()
{
return m_pcPointer;
}
};
class CTest
{
int
m_nTest;

public:
CTest() : m_nTest(123) {}

void Testing()
{
int
i = 0;
}
};

typedef TAutoPointer < CTest* > CTestAutoPtr;

int main(int argc, char* argv[])
{
CTestAutoPtr
cAP(new CTest);
cAP->Testing();

return 0;
}

Jul 22 '05 #1
4 1749
PKH wrote:
This is a part of an autopointer template i'm using. I originally had a
Get() member that returned the pointer, but thought it would nice to be
able to use the -> operator.
The question is why does the following line work, and call
cAP.m_pcPointer->Testing() ?

cAP->Testing(); // ???

cAP-> returns a CTest*, so it looks to me like the line reads
cAP.m_pcPointer <whitespace> Testing(), but it actually does
cAP.m_pcPointer->Testing(). I thought maybe it would be called with a bad
this-pointer, but it's the this-pointer is correct inside Testing(). What
am I not seeing here ?


You're not making a difference between the operator-> and the x->y
statement. cAp->Testing() will first execute operator-> for cAp and then
call Testing on the returned pointer.
If you want to do that explicitly, you can write:

cAP.operator->()->Testing();

Jul 22 '05 #2
PKH wrote:
[snip] The question is why does the following line work, and call
cAP.m_pcPointer->Testing() ?

cAP->Testing(); // ???

cAP-> returns a CTest*, so it looks to me like the line reads
cAP.m_pcPointer <whitespace> Testing(), but it actually does
cAP.m_pcPointer->Testing(). I thought maybe it would be called with a bad
this-pointer, but it's the this-pointer is correct inside Testing(). What am
I not seeing here ?


The returned pointer from operator-> is automatically dereferenced
for you in any case. So operator-> is a little bit special, as
it doesn't return the final 'result' of the operation, but it's
result is used for an additional operation. Same with operator*()

Without that behaviour it would not be possible to use those
operators without major syntax changes.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #3

"PKH" <no************@online.no> schrieb im Newsbeitrag
news:19********************@news4.e.nsc.no...
This is a part of an autopointer template i'm using. I originally had a
Get() member that returned the pointer, but thought it would nice to be able to use the -> operator.
The question is why does the following line work, and call
cAP.m_pcPointer->Testing() ?

cAP->Testing(); // ???

cAP-> returns a CTest*, so it looks to me like the line reads
cAP.m_pcPointer <whitespace> Testing(), but it actually does
cAP.m_pcPointer->Testing(). I thought maybe it would be called with a bad
this-pointer, but it's the this-pointer is correct inside Testing(). What am I not seeing here ?
template <class T> class TAutoPointer
{
private:
T
m_pcPointer;

public:
TAutoPointer(T t) : m_pcPointer(t) {}
~TAutoPointer(){if (m_pcPointer) delete m_pcPointer;}

T& operator -> ()
{
return m_pcPointer;
}
};
class CTest
{
int
m_nTest;

public:
CTest() : m_nTest(123) {}

void Testing()
{
int
i = 0;
}
};

typedef TAutoPointer < CTest* > CTestAutoPtr;

int main(int argc, char* argv[])
{
CTestAutoPtr
cAP(new CTest);
cAP->Testing();

return 0;
}


The magic of operator -> !

operator -> is an unary (!) operator, and it's overloading has a very
special meaning:
an overloaded operator -> must return something to that another operator ->
can be applied.

An example for illustration:

struct S { int i; }
S s = { 4711 };

class X
{
public:
S* operator->() { return &s; }
};

class Y
{
public:
X operator->() { return X(); }
};

class Z
{
public:
Y operator->() { return Y(); }
};

Z z;
int v = z->i;

Here, v will be initialized with 4711!
Why? "z->" results to an object of type Y, which has an operator->. This
operator results to an X with an operator-> resulting an pointer S*. To this
pointer the simple C++ operator-> for pointers can be applied and gives the
value of s.i .
So
int v = z->i;
will be compiled as
int v = z.Z::operator->().Y::operator->().X::operator->()->i;

In your code cAP-> results to an CTest*& to which the operator -> for
pointers will be applied and call CTest::Testing().

Greeting from Cologne, Germany
Georg
Jul 22 '05 #4
PKH
Ok, thanks for clearing that up. I didn't know the operator worked like
that.

PKH

"Georg Krichel" <so***@no.spam> wrote in message
news:bP**************@s080a1060.group.rwe.com...

"PKH" <no************@online.no> schrieb im Newsbeitrag
news:19********************@news4.e.nsc.no...
This is a part of an autopointer template i'm using. I originally had a
Get() member that returned the pointer, but thought it would nice to be

able
to use the -> operator.
The question is why does the following line work, and call
cAP.m_pcPointer->Testing() ?

cAP->Testing(); // ???

cAP-> returns a CTest*, so it looks to me like the line reads
cAP.m_pcPointer <whitespace> Testing(), but it actually does
cAP.m_pcPointer->Testing(). I thought maybe it would be called with a
bad
this-pointer, but it's the this-pointer is correct inside Testing(). What

am
I not seeing here ?
template <class T> class TAutoPointer
{
private:
T
m_pcPointer;

public:
TAutoPointer(T t) : m_pcPointer(t) {}
~TAutoPointer(){if (m_pcPointer) delete m_pcPointer;}

T& operator -> ()
{
return m_pcPointer;
}
};
class CTest
{
int
m_nTest;

public:
CTest() : m_nTest(123) {}

void Testing()
{
int
i = 0;
}
};

typedef TAutoPointer < CTest* > CTestAutoPtr;

int main(int argc, char* argv[])
{
CTestAutoPtr
cAP(new CTest);
cAP->Testing();

return 0;
}


The magic of operator -> !

operator -> is an unary (!) operator, and it's overloading has a very
special meaning:
an overloaded operator -> must return something to that another
operator ->
can be applied.

An example for illustration:

struct S { int i; }
S s = { 4711 };

class X
{
public:
S* operator->() { return &s; }
};

class Y
{
public:
X operator->() { return X(); }
};

class Z
{
public:
Y operator->() { return Y(); }
};

Z z;
int v = z->i;

Here, v will be initialized with 4711!
Why? "z->" results to an object of type Y, which has an operator->. This
operator results to an X with an operator-> resulting an pointer S*. To
this
pointer the simple C++ operator-> for pointers can be applied and gives
the
value of s.i .
So
int v = z->i;
will be compiled as
int v = z.Z::operator->().Y::operator->().X::operator->()->i;

In your code cAP-> results to an CTest*& to which the operator -> for
pointers will be applied and call CTest::Testing().

Greeting from Cologne, Germany
Georg

Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Joe Seigh | last post by:
Is there a good write on this. The textbooks I have fluff over on this? Specifically, I trying to dereference with 2 levels of type conversion not 1, i.e. X<T> -> z => Y<T> -> z => T* ->...
16
by: Edward Diener | last post by:
Is there a way to override the default processing of the assignment operator for one's own __value types ? I realize I can program my own Assign method, and provide that for end-users of my class,...
16
by: gorda | last post by:
Hello, I am playing around with operator overloading and inheritence, specifically overloading the + operator in the base class and its derived class. The structure is simple: the base class...
2
by: pmatos | last post by:
Hi all, I'm overloading operator<< for a lot of classes. The question is about style. I define in each class header the prototype of the overloading as a friend. Now, where should I define the...
67
by: carlos | last post by:
Curious: Why wasnt a primitive exponentiation operator not added to C99? And, are there requests to do so in the next std revision? Justification for doing so: C and C++ are increasingly used...
4
by: Tony Johansson | last post by:
Hello!! I have done some operator overloading but my main testprogram doesn't work well. Have you any idea which of my methods are wrong? #include <iostream> #include <string> using...
6
by: jay | last post by:
In the c++ primer ,i get a program. A class's name is TT,and it define the operator overload! TT first; //constructor TT second(30);//constructor TT thrid(40://constructor...
5
by: Jerry Fleming | last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone says that the four operators can only be overloaded with class member functions instead of global (friend) functions: (), ,...
1
by: Nikhil.S.Ketkar | last post by:
Hi, Does the following construct qualify as overloading on return type ? If not, in what way ? I overloaded the type conversion operator and used pointers to member functions. Its pretty...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

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.