471,570 Members | 995 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

Overloading the typecast operator

There's a rather nondescript book called "Using Borland C++" by Lee
and Mark Atkinson (Que Corporation) which presents a rather good
discussion of typecast operator overloading.

I am presenting below a summary of what I have gathered. I would
appreciate if someone could point out to something that is specific to
Borland C++ and is not supported by the ANSI standard. I am also
concerned that some of the information may be outdated since the book
is quite old (1991 edition).

1). Cast operator functions are declued using the following syntax:
operator typename ();
operator typename* ();

2). The target type of the conversion cannot be an enumeration or a
typedef name.

3). You rannot specify a return type.

4). You cannot declare arguments for a cast operator function. It is
assumed that
the function is dealing with *this as input.

5). Cast operator functions are inherited and they can be virtual
functions

6). Only one cast operator function can be implicitly applied to a
class object

7). Cast operator functions cannot be overloaded

8). A cast operator function in a derived class hides a cast operator
function in its base class only if the target type is exactly the
same.

9). The cast operator functions are used in serializing operations.

// ~~~~~~~ Code snippet begin ~~~~~~~
#include <iostream.h>

//////////////////////////////////////////////////////
class A
{
int dat;

public:
A(int num = 0 ) : dat(num) {}

operator int() {return dat;} // castop to int
};
//////////////////////////////////////////////////////
class X
{
int dat;

public:
X(int num = 0) : dat(num){}

operator int() {return dat;} // castop to int

operator A() // castop to class A
{
A temp = dat;
return temp;
}
};
//////////////////////////////////////////////////////
int main()
{
X stuff = 37;
A more = 0;
int hold;

hold = (int)stuff;
cout << hold << endl;

more = stuff; // convert X::stuff to A::more
hold = (int)more; // convert A::more to int
cout << hold << endl;
}
// ~~~~~~~ Code snippet end ~~~~~~~

Regards,
Nimmi
Jul 22 '05 #1
2 18327
Nimmi Srivastav wrote:
There's a rather nondescript book called "Using Borland C++" by Lee
and Mark Atkinson (Que Corporation) which presents a rather good
discussion of typecast operator overloading.

I am presenting below a summary of what I have gathered. I would
appreciate if someone could point out to something that is specific to
Borland C++ and is not supported by the ANSI standard. I am also
concerned that some of the information may be outdated since the book
is quite old (1991 edition).

1). Cast operator functions are declued using the following syntax:
operator typename ();
operator typename* ();
They are actually not "cast operators", but "conversion operators". And
your second operator is just the same as the first, with typename being
a pointer type.
2). The target type of the conversion cannot be an enumeration or a
typedef name.
I don't see any reason for that. Should both work. Especially the
typedef is just an alias for another type. Wherever you can use the
original type, you can use the typedef too.
3). You rannot specify a return type.
Right. The return type is always the same as the "target type" and must
not be specified again.
4). You cannot declare arguments for a cast operator function.
Right. How could you call it with arguments?
It is assumed that the function is dealing with *this as input.
That's the case for any member function.
5). Cast operator functions are inherited and they can be virtual
functions
Yes.
6). Only one cast operator function can be implicitly applied to a
class object
One implicit conversion is done, be it through a conversion constructor
or a conversion oprerator.
7). Cast operator functions cannot be overloaded
Not quite true. You can have const and non-const overloads.
8). A cast operator function in a derived class hides a cast operator
function in its base class only if the target type is exactly the
same.
Yes. If it's not, it's another conversion operator.
9). The cast operator functions are used in serializing operations.
This is just one example where they might be used. I don't see that as
something that is especially connected to conversion operators.

// ~~~~~~~ Code snippet begin ~~~~~~~
#include <iostream.h>
This is an outdated pre-standard header. Use <iostream> instead.
Everything in there (like cout) will be in namespace std then.

//////////////////////////////////////////////////////
class A
{
int dat;

public:
A(int num = 0 ) : dat(num) {}

operator int() {return dat;} // castop to int
};
//////////////////////////////////////////////////////
class X
{
int dat;

public:
X(int num = 0) : dat(num){}

operator int() {return dat;} // castop to int

operator A() // castop to class A
{
A temp = dat;
return temp;
}
Whenever possible, you should use a conversion constructor in the target
class instead of a conversion operator in the source class. So instead
of that operator A() in X, you should add a constructor to A like:

A(const X& rhs)
: dat(rhs)
{}

This will directly construct the A object from the X object instead of
first default-constructing it and then changing it. Another reason is
that you can make conversion constructors explicit.
But for this to work, your operator int() in X has to be const, like:

operator int() const {return dat;}
};
//////////////////////////////////////////////////////
int main()
{
X stuff = 37;
A more = 0;
int hold;

hold = (int)stuff;
You don't need to cast here, the conversion is done implicitly. You
should also avoid C style casts and use the more fine-grained C++
casts.
cout << hold << endl;
You could just directly write this as:

cout << stuff << endl;

The conversion will be done implicitly.
more = stuff; // convert X::stuff to A::more
hold = (int)more; // convert A::more to int
You can skip that cast, too. Done implicitly.
cout << hold << endl;
}
// ~~~~~~~ Code snippet end ~~~~~~~

Jul 22 '05 #2
"Rolf Magnus" <ra******@t-online.de> wrote in message
news:bv*************@news.t-online.com...
Nimmi Srivastav wrote:
2). The target type of the conversion cannot be an enumeration or a typedef name.


I don't see any reason for that. Should both work. Especially the
typedef is just an alias for another type. Wherever you can use the
original type, you can use the typedef too.


True. Also, in some cases, a typedef is absolutely necessary, e.g.
when converting to a pointer to an array:

struct Thing {
typedef int (*array) [9];
operator array(); // okay
operator int (*) [9] (); // syntax error
};

<snip>
4). You cannot declare arguments for a cast operator function.


Right. How could you call it with arguments?


If they had default values. This would actually be very conveinent: it
would allow the use of the enable_if utility with conversion
operators. (CUJ June 2003)

Jonathan
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Zenon | last post: by
5 posts views Thread by | last post: by
1 post views Thread by masood.iqbal | last post: by
5 posts views Thread by luca regini | last post: by
3 posts views Thread by ryan.gilfether | last post: by
3 posts views Thread by y-man | last post: by
2 posts views Thread by Colonel | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by lumer26 | last post: by
reply views Thread by lumer26 | last post: by
reply views Thread by lumer26 | last post: by

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.