-
March 3rd, 2004, 11:11 AM
#1
Overloading -> and * operators
I have a strange problem with overloading the -> and * operators. I'm trying to do this to make dereferencing a pointer to the class intrinsically safe. I think the problem is the same in both cases, so I'll describe the * operator:
In myreal.h:
Code:
const CMyReal& operator * (void);
and in myreal.cpp
Code:
const CMyReal& CMyReal::operator * (void)
{
if (this)
return *this;
else
return CMyReal::Bad;
}
where CMyReal::Bad is a static object representing Not-A-Number.
Now, when I write:
Code:
CMyReal *myreal = NULL;
float x = (myreal->operator *()).value();
it calls my overloaded operator function and I get Not-A-Number, as expected.
But if I write
Code:
float x = (*myreal).value();
it doesn't call the overloaded operator function but tries to dereference the NULL pointer directly and I get an access violation error.
Similarly, (myreal->operator ->())->value() is ok, but myreal->value() fails with an access violation.
Any idea what I am doing wrong?
-
March 3rd, 2004, 11:40 AM
#2
Try making your operator* a non-member function:
Code:
class CMyReal
{
// stuff
};
const CMyReal& operator*(const CMyReal* obj)
{
if (obj)
return *obj;
else
return CMyReal::Bad;
}
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
March 3rd, 2004, 12:16 PM
#3
The compile won't have that:
error C2803: 'operator *' must have at least one formal parameter of class type
Also, operator -> must be a member function according to the spec.
-
March 3rd, 2004, 01:02 PM
#4
Unfortunately, your override of operator * in your CMyReal class only affects the use of a * when you have an object of type CMyReal. You are trying to use it on a pointer to a CMyReal, which is not the same type.
As soon as you introduce a raw pointer, you aren't going to be able to override the operator * and get a dereference of the raw pointer to call your overridden routine.
I don't know if this is at all useful to you, but you could wrap the pointer inside of a class - something like:
Code:
class CMyRealPtr
{
private:
static CMyReal Bad;
CMyReal* m_ptr;
public:
CMyRealPtr( CMyReal* ptr = NULL ) : m_ptr( ptr )
{
}
const CMyReal& operator*()
{
if ( m_ptr )
return *m_ptr;
return Bad;
}
};
CMyReal CMyRealPtr::Bad( -1 );
int main()
{
CMyRealPtr myreal = NULL;
float x = (myreal.operator *()).value();
float y = (*myreal).value();
return 0;
}
Now the pointer is not a raw pointer anymore, but is instead an object. The explicit call to operator * and the dereference of the myreal object both call the operator* member of CMyRealPtr.
Best regards,
John
-
March 3rd, 2004, 01:48 PM
#5
I knew there was something wrong with my reply as I was typing it, but I couldn't think what it was. Symbian - it rots your C++ brain, you know.
jwbarton has it correct - the operator* and operator-> need to be members of a class that wraps the pointer, not members of the target class. boost::smart_ptr would be a good starting place.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
March 4th, 2004, 04:25 AM
#6
John (and Graham),
Thanks very much for your replies. I think I understand it now. I guess this is very closely related to the 'smart pointer' templates that are available for C++. I had this idea that by simply overriding an operator, I could make my class intriniscally safe without requiring the caller to change the way it called the class and with no additional overhead. I'm really a C programmer...
I suppose the real surprise here is that the ->operator * () version worked at all. Come to think of it,
Code:
myreal->operator *()
when myreal is NULL looks decidedly dodgy
Anyway, thanks for your time.
Ian
Last edited by iangoldby; March 4th, 2004 at 04:35 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|