Thread: question about overloading operators

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    question about overloading operators

    Code:
    &#160;&#160;&#160;const&#160;complex<T>&&#160;operator&#160;[](int&#160;i)&#160;const&#160;{&#160;return&#160;data[i];&#160;};
    
    &#160;&#160;&#160;cvector&#160;operator&#160;+(cvector&&#160;A)&#160;{&#160;&#160;//&#160;ADDITION&#160;OPERATOR
    &#160;&#160;&#160;&#160;&#160;&#160;cvector&#160;result(A.size);&#160;&#160;//&#160;DO&#160;NOT&#160;MODIFY&#160;THE&#160;ORIGINAL
    &#160;&#160;&#160;&#160;&#160;&#160;for&#160;(int&#160;i&#160;=&#160;0;&#160;i&#160;<&#160;size;&#160;i++)
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;result[i]&#160;=&#160;data[i]&#160;+&#160;A.data[i];
    &#160;&#160;&#160;&#160;&#160;&#160;return&#160;result;
    &#160;&#160;&#160;&#160;&#160;&#160;};
    why is it that you cannot reference the class' overloaded operators, namely the [] operator; like so:

    Code:
       
    
    const complex<T>& operator [](int i) const { return data[i]; };
    
       cvector operator +(cvector& A) {  // ADDITION OPERATOR
          cvector result(A.size);  // DO NOT MODIFY THE ORIGINAL
          for (int i = 0; i < size; i++)
              result[i] = this[i] + A[i];
          return result;
          };
    ?

    why is it that you can use the bracket operator for result, but not A or this?
    Last edited by m37h0d; 07-15-2008 at 08:40 PM.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I think you'll have to post more information to get a definitive answer (like cvector's overloaded operator []).

    Make sure you're not trying to recursively access the overloaded operator from inside itself, and that you're not overstepping the boundaries of permissions when you try to access class members.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    this is a pointer, you must dereference it:
    Code:
    (*this)[i]
    A should work as-is. Is this a templated class? (You may need to supply more info to the templates)

    Also, you can add in some const-correctness in the + operator. Don't just comment that it's not going to change - make it so.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    I think you'll have to post more information to get a definitive answer (like cvector's overloaded operator []).
    i did, actually; it's just in one line.

    Code:
    const complex<T>& operator [](int i) const { return data[i]; };
    and no, i'm not reinventing the wheel, these are c&p'd from my compiler's help files...
    Last edited by m37h0d; 07-15-2008 at 08:53 PM.

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    this is a pointer, you must dereference it:
    this[0] is a valid expression elsewhere in the class implementation; it just doesn't seem to like using other overloaded operators in an operator's implementation. i made sure that [] was defined and implemented first (not that it should matter), but it doesn't want to let me use it in the implementation of +, -, etc.

    Code:

    (*this)[i]

    A should work as-is. Is this a templated class? (You may need to supply more info to the templates)
    no, the class i'm overloading the operators for is not a template; these are just the help files i'm using for examples.

    and no, result[i]=this->data[i]+A[i] does not work either.

    i just don't understand why i can use [] on the LHS but not the RHS
    Last edited by m37h0d; 07-15-2008 at 09:01 PM.

  6. #6
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    this[0] is a valid expression elsewhere in the class implementation; it just doesn't seem to like using other overloaded operators in an operator's implementation.
    this[0] does not call any overload operators in your class. "this" is a pointer. this[0] is valid (albeit strange, I wouldn't use.), this[1] is invalid. Neither call an overloaded operator. (*this) += 2 calls the classes overloaded operator +=. (*this)[i] calls the the classes overloaded operator [].

    You have this in your code:
    Code:
    const complex<T>&
    Which seemed to indicate templates somewhere.

    Show us more code, and any errors you get, and where they occur.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Code:
    class spectrum
    {
            public:
            spectrum(spectrometer *Owner,const unsigned short arrSize,String Title);
            spectrometer *owner;
    
            unsigned short size;
            double *data;
            void __fastcall fill(double val);
            String title;
            double max;
            String __fastcall asString();
            ~spectrum()
            {
                    delete[] data;
                    delete &title;
                    delete &max;
                    delete &size;
            }
            double &operator [](const int i)
            {
                    return data[i];
            }
            spectrum operator +(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] + A.data[i];
                    }
                    return result;
            };
            spectrum operator *(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] * A.data[i];
                    }
                    return result;
            };
            spectrum operator -(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] - A.data[i];
                    }
                    return result;
            };
            spectrum operator /(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] / A.data[i];
                    }
                    return result;
            };
            operator -=(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    int i=-1;
                    while(++i<rsize)
                    {
                            data[i]-= A.data[i];
                    }
            };
            operator +=(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    int i=-1;
                    while(++i<rsize)
                    {
                            data[i]+= A.data[i];
                    }
            };
    
            operator *=(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    int i=-1;
                    while(++i<rsize)
                    {
                            data[i]*= A.data[i];
                    }
            };
            operator /=(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    int i=-1;
                    while(++i<rsize)
                    {
                            data[i]/= A.data[i];
                    }
            };
            operator =(const unsigned short *A)
            {
                    int i=-1;
                    while(++i<size)
                    {
                            data[i]= (double)A[i]/65536;
                    }
            };
    };

  8. #8
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    the above doesn't create errors; but the exact same behavior still persists;

    this works:
    Code:
    spectrum operator +(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] + A.data[i];
                    }
                    return result;
            };
    this doesn't:

    Code:
    spectrum operator +(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] + A[i];
                    }
                    return result;
            };
    i get:
    "operator+" not implemented in type 'spectrum' for arguments of type 'int'
    Last edited by m37h0d; 07-15-2008 at 09:25 PM.

  9. #9
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by Cactus_Hugger View Post
    this[0] does not call any overload operators in your class. "this" is a pointer. this[0] is valid (albeit strange, I wouldn't use.), this[1] is invalid. Neither call an overloaded operator. (*this) += 2 calls the classes overloaded operator +=. (*this)[i] calls the the classes overloaded operator [].

    You have this in your code:
    Code:
    const complex<T>&
    Which seemed to indicate templates somewhere.

    Show us more code, and any errors you get, and where they occur.
    right, of course. this[0] == this; this[1]==this+1...

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by m37h0d View Post
    Code:
    class spectrum
    {
            public:
            spectrometer *owner;
    
            unsigned short size;
            double *data;
            void __fastcall fill(double val);
            String title;
            double max;
            String __fastcall asString();
            ~spectrum()
            {
                    delete[] data;
                    delete &title;
                    delete &max;
                    delete &size;
            }
    };
    don't delete size, max and title like that. You didn't call new on them anywhere, so you don't call delete.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    ok, thanks. i wasn't sure about that actually. i figured someone would hit on that

  12. #12
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Some more notes:
    1) All of your member variables are public. Re-evaluate what needs to be public.

    2) Many of your operators (namely, +=, -=, *=, /= and =) need return types. Usually you return (in this case) a spectrum &, and do a return *this;.

    3) On many of your operators, they should be const, like:
    Code:
    spectrum operator -(const spectrum &A) const
    (I added that last const)

    4) Finally, this:
    Code:
    spectrum operator +(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] + A[i];
                    }
                    return result;
            };
    The error you get is odd, but. A[i] will fail as there is no applicable [] operator here - A is const, as it should be. Provide another version of the [] operator that is const (and will probably return a const reference to your data)
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  13. #13
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by Cactus_Hugger View Post
    Some more notes:
    1) All of your member variables are public. Re-evaluate what needs to be public.
    that is one of the goals of writing these operators. i can hide data, and possibly others.


    Quote Originally Posted by Cactus_Hugger View Post
    2) Many of your operators (namely, +=, -=, *=, /= and =) need return types. Usually you return (in this case) a spectrum &, and do a return *this;.
    i had thought about that, but the examples didn't cover +=, etc. operators. they did give a copy constructor example, but i was not sure i needed to return a reference to self since the implementation of those operators altered the data of the operand.

    Quote Originally Posted by Cactus_Hugger View Post
    3) On many of your operators, they should be const, like:
    Code:
    spectrum operator -(const spectrum &A) const
    (I added that last const)

    4) Finally, this:
    Code:
    spectrum operator +(const spectrum &A)
            {
                    int rsize = size;
                    if(A.size<size)
                    {
                            rsize = A.size;
                    }
                    spectrum result(owner,rsize,"result");
                    int i=-1;
                    while(++i<rsize)
                    {
                            result[i]=data[i] + A[i];
                    }
                    return result;
            };
    The error you get is odd, but. A[i] will fail as there is no applicable [] operator here - A is const, as it should be. Provide another version of the [] operator that is const (and will probably return a const reference to your data)
    a ha. i was not familiar with the use of const in this context. i read up on it a bit; seems reasonable enough.

    so the only ones that should not be const members are the assignment operators i suppose?
    Last edited by m37h0d; 07-15-2008 at 10:30 PM.

  14. #14
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    i had thought about that, but the examples didn't cover +=, etc. operators.
    Well, think of it this way. Take this:
    Code:
    AType a, b, c;
    a += b += c;
    // or even more simple:
    a = b = c;
    First, everything in C++ needs a return type. (It can be void, but not specifying one is an error) To make the above work, however, we need to return (in my example's case) a AType &.

    so the only ones that should not be const members are the assignment operators i suppose?
    No? (Not terribly sure on your question here...) Take it on a case-by-case basis. As a rule of thumb, if you don't change the class, make it const reference. Let's take this example:
    Code:
    AType a, b, c;
    a = b - c;
    Here, I would not expect b OR c to change during the - operator. So, this gives way to the operator:
    Code:
    AType Atype::operator - (const AType &rhs) const {
    The rhs is const - it's c in the example - because we shouldn't need to change it in a - operator. (As a user, I'd be shocked if it did change.). Same for the last const (on "this"), which is b in the example, and should also not change. (if b or c did change in that example, that would signal a design that needs to be looked at.)

    Edit: The need for two [] operators arise out of the following:
    If the class is const, you need a const [] that returns a const reference, because nothing can change. (it's const!)
    If the class is not const, we can still use the const [], but it doesn't do us any good if we want to change things (the return of the const [] is const itself, for good reason) - so we write the non const version
    Last edited by Cactus_Hugger; 07-15-2008 at 10:58 PM.

  15. #15
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    yep; you're correct. implementing a const bracket operator allows me to use it in the other overloaded operators. that error message was very misleading.

    so, i suppose if i had (incorrectly) not defined the argument as a const object, i would not have needed the const bracket operator?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 25
    Last Post: 11-30-2008, 11:30 PM
  2. Newbie with C++ NOT, OR, AND operators question...
    By JiWiz in forum C++ Programming
    Replies: 4
    Last Post: 07-27-2008, 11:05 AM
  3. Replies: 2
    Last Post: 07-28-2006, 02:59 PM
  4. Replies: 9
    Last Post: 05-19-2006, 05:19 PM
  5. overloading operators..please help
    By Tozilla in forum C++ Programming
    Replies: 5
    Last Post: 03-29-2003, 11:32 PM