Re: Operator Overloading - references?

Discussion in 'C++' started by =?ISO-8859-1?Q?Gamb=E1?=, Jun 25, 2003.

  1. "John Harrison" <> wrote in message news:<bcu2eo$mnfk8$>...
    > All you examples are wrong, which books are you reading? I can't believe


    http://www.desy.de/gna/html/cc/Tutorial/node10.htm
    That one... They didn't use const on the second example (the one that
    suited my needs better, even being slower), so so didn't I.


    > Object operator+ (const Object &A, const Object &B) { /* do stuff */ }
    > Object &Object::eek:perator= (const Object &B) { /* copy stuff */ }
    > Parameter is const, return type is not.
    > Object &Object::eek:perator+= (const Object &B) { /* add stuff */ }
    > Parameter is const, return type is not.


    > The return of a function or operator is called a temporary. C++ has a rule,
    > you cannot bind a non-const reference to a temporary. The solution is to
    > make the reference required by operator* (and all your other operators)
    > const.


    > > What am I doing wrong?

    > See above.


    Well, I did all these changes to consts, and the compiler seems to not
    have liked it. All calls to methods in the code have an error message
    similar to this:

    Polinomio.G02.cpp:19: passing `const Polinomio' as `this' argument of
    `unsigned int Polinomio::grau ()' discards qualifiers


    > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.hpp
    > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.cpp


    > I can see from the above links that you class doesn't not use const at all.
    > For instance


    > string toString ();
    > should be
    > string toString () const;


    But string is the return type. And there is no argument. Why is this
    const there at all?


    :: Ekevu/Gambá ::
     
    =?ISO-8859-1?Q?Gamb=E1?=, Jun 25, 2003
    #1
    1. Advertising

  2. =?ISO-8859-1?Q?Gamb=E1?=

    Hiram Berry Guest

    Gambá,
    Rearranging the order of your questions,

    "Gambá" <> wrote in message
    news:...
    > "John Harrison" <> wrote in message

    news:<bcu2eo$mnfk8$>...

    > > I can see from the above links that you class doesn't not use const at

    all.
    > > For instance

    >
    > > string toString ();
    > > should be
    > > string toString () const;

    >
    > But string is the return type. And there is no argument. Why is this
    > const there at all?


    Putting the "const" keyword after a member function declaration makes the
    member function itself const-- it promises not to change the internal state
    of its own class object. This syntax is only applied to nonstatic member
    functions, because static member functions are not associated with a
    particular object of the class. If a nonstatic member just outputs the
    state of an object and doesn't change any member variables, it should be
    declared "const" as John did above.

    An object which is considered const, either via declaration or as an
    argument to a function which takes a const & parameter, may only call member
    functions that are declared const. That's the problem you're running into
    with your Polinomio class.

    >
    > Well, I did all these changes to consts, and the compiler seems to not
    > have liked it.


    Yes, this is a common experience when you refactor old code to be
    const-correct. You just have to trace through the code and see where the
    assumptions about what should be const are violated, and then fix them.

    > All calls to methods in the code have an error message
    > similar to this:
    >
    > Polinomio.G02.cpp:19: passing `const Polinomio' as `this' argument of
    > `unsigned int Polinomio::grau ()' discards qualifiers
    >
    >
    > > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.hpp
    > > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.cpp

    >

    Well, I looked at it. In that particular case you have at least one
    function, operator=, that takes a "const Polinomio &" parameter, and then
    calls the member function grau() on the object referred by the reference
    parameter:

    Polinomio &Polinomio::eek:perator= (const Polinomio &outro) {
    int i;
    G = outro.grau();

    Within the body of that function, "outro" is considered to be const. Only
    const member functions may be called on it, but "grau()" was not declared
    const, so the compiler flags an error. You must declare "unsigned
    Polinomio::grau() const;" so that operator=() can call it on the object
    const referenced by outro.

    Doing so will spawn another error that you should also fix. Const member
    functions are not ordinarily allowed to change member variables of their
    object. "grau()" however can at least potentially change the variable
    "Polinomio::G" . C++ has a workaround for cases like this, where a minor
    violation of const-correctness is reasonably allowed: the "mutable" keyword.
    Placed before a member variable declaration it says "const member functions
    are allowed to change the value of this variable without causing a
    compilation error". So in the Polinomio class declaration you need:

    mutable unsigned int G;

    With those two changes, operator=() can call the const member function
    grau() on the const reference outro, and grau() in turn may possibly change
    the value of outro's mutable member variable G, even though grau() is const.

    If there are other errors like this, they can probably be solved in the same
    manner.

    HTH,

    Hiram
     
    Hiram Berry, Jun 25, 2003
    #2
    1. Advertising

  3. "Gambá" <> wrote in message
    news:...
    > "John Harrison" <> wrote in message

    news:<bcu2eo$mnfk8$>...
    > > All you examples are wrong, which books are you reading? I can't believe

    >
    > http://www.desy.de/gna/html/cc/Tutorial/node10.htm
    > That one... They didn't use const on the second example (the one that
    > suited my needs better, even being slower), so so didn't I.
    >


    I think that is an oversight.

    >
    > > Object operator+ (const Object &A, const Object &B) { /* do stuff */ }
    > > Object &Object::eek:perator= (const Object &B) { /* copy stuff */ }
    > > Parameter is const, return type is not.
    > > Object &Object::eek:perator+= (const Object &B) { /* add stuff */ }
    > > Parameter is const, return type is not.

    >
    > > The return of a function or operator is called a temporary. C++ has a

    rule,
    > > you cannot bind a non-const reference to a temporary. The solution is to
    > > make the reference required by operator* (and all your other operators)
    > > const.

    >
    > > > What am I doing wrong?

    > > See above.

    >
    > Well, I did all these changes to consts, and the compiler seems to not
    > have liked it. All calls to methods in the code have an error message
    > similar to this:
    >
    > Polinomio.G02.cpp:19: passing `const Polinomio' as `this' argument of
    > `unsigned int Polinomio::grau ()' discards qualifiers


    Right, so change grau to be a const method.

    class Polinomio
    {
    ...
    unsigned int grau() const;
    ...
    };

    >
    >
    > > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.hpp
    > > > http://www.inf.ufrgs.br/~omarb/Polinomio.G02.cpp

    >
    > > I can see from the above links that you class doesn't not use const at

    all.
    > > For instance

    >
    > > string toString ();
    > > should be
    > > string toString () const;

    >
    > But string is the return type. And there is no argument. Why is this
    > const there at all?
    >


    Because toString does not modify the Polinomio object. All methods that can
    be declared const should be. That will enable you to call those methods on
    const objects, which will allow you to declare your operators with const
    references. Which will allow you to use them without the problems you are
    having.

    In C you can get away without understanding or using const, in C++ you
    cannot.

    john
     
    John Harrison, Jun 25, 2003
    #3
  4. >
    > Doing so will spawn another error that you should also fix. Const member
    > functions are not ordinarily allowed to change member variables of their
    > object.


    For hopefully obvious reasons.

    > "grau()" however can at least potentially change the variable
    > "Polinomio::G" . C++ has a workaround for cases like this, where a minor
    > violation of const-correctness is reasonably allowed: the "mutable"

    keyword.
    > Placed before a member variable declaration it says "const member

    functions
    > are allowed to change the value of this variable without causing a
    > compilation error". So in the Polinomio class declaration you need:
    >
    > mutable unsigned int G;
    >


    Looking at the code, C also needs to be declared mutable as well. So we have
    a class where everything is mutable. It works but suggests to me that a
    redesign might be a better solution.

    john
     
    John Harrison, Jun 25, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Smith
    Replies:
    2
    Views:
    448
    Ivan Vecerina
    Oct 6, 2004
  2. Replies:
    11
    Views:
    767
    James Kanze
    May 16, 2007
  3. hurcan solter
    Replies:
    3
    Views:
    755
    Cholo Lennon
    Aug 29, 2007
  4. Replies:
    11
    Views:
    584
  5. Replies:
    2
    Views:
    334
Loading...

Share This Page