CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jan 2000
    Location
    Nottingham, UK
    Posts
    51

    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?

  2. #2
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    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


  3. #3
    Join Date
    Jan 2000
    Location
    Nottingham, UK
    Posts
    51
    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.

  4. #4
    Join Date
    Jan 2001
    Posts
    253
    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

  5. #5
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    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


  6. #6
    Join Date
    Jan 2000
    Location
    Nottingham, UK
    Posts
    51
    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
  •  





Click Here to Expand Forum to Full Width

Featured