operator overloading simple question

S

Sam Hu

Dir Sirs,

This is just a question from a C++ newbie regarding the operator
overloading.Since I do not want to use friend key word,I write class
graduate as below:

//graduate.h
#ifndef GRADUATE_H
#define GRADUATE_H

#include <iostream>
#include <string>

using namespace std;

class graduate
{
public:
/** Default constructor */
graduate();
string getDegree() const;
bool isEqual(const graduate& rhs);
bool lessThan(const graduate& rhs);

istream& getfrom(istream& istr)const;
ostream& sendto(ostream& ostr)const;

protected:
private:
string name;
string degree;
};
bool operator==(const graduate& lhs,graduate& rhs)
{
return lhs.isEqual(rhs);
}
bool operator<(const graduate& lhs,graduate& rhs)
{
return lhs.lessThan(rhs);

}
istream& operator>>(istream& istr,const graduate& grad)const
{
return grad.getfrom(istr);
}
ostream& operator<<(ostream& ostr,const graduate& grad)const
{
return grad.sendto(ostr);
}
graduate::graduate()
{
//ctor
}
/** @brief getDegree
*
* @todo: document this function
*/
string graduate::getDegree() const
{
return degree;
}

/** @brief getfrom
*
* @todo: document this function
*/
istream & graduate::getfrom(istream& istr)const
{
char ch;
istr>>this.name;
istr>>ch;
istr>>this.degree;
return istr;


}

/** @brief isEqual
*
* @todo: document this function
*/
bool graduate::isEqual(const graduate& rhs)
{
return this.name==rhs.name;
}

/** @brief sendto
*
* @todo: document this function
*/
ostream & graduate::sendto(ostream& ostr)const
{
ostr<<"Name:"<< this.name<<"\tdegree:"<<this.degree<<endl;
return ostr;
}
/** @brief lessThan
*
* @todo: document this function
*/
bool graduate::lessThan(const graduate& rhs)
{
return this.name<rhs.name;

}



#endif // GRADUATE_H
//end of graduate.h
Compiler generates a lot of error message:
F:\CodeBlocksProject\listApp\graduate.h||In function `bool operator==
(const graduate&, graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|28|error: passing `const
graduate' as `this' argument of `bool graduate::isEqual(const
graduate&)' discards qualifiers|
F:\CodeBlocksProject\listApp\graduate.h||In function `bool operator<
(const graduate&, graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|32|error: passing `const
graduate' as `this' argument of `bool graduate::lessThan(const
graduate&)' discards qualifiers|
F:\CodeBlocksProject\listApp\graduate.h|36|error: non-member function
`std::istream& operator>>(std::istream&, const graduate&)' cannot have
`const' method qualifier|
F:\CodeBlocksProject\listApp\graduate.h|40|error: non-member function
`std::eek:stream& operator<<(std::eek:stream&, const graduate&)' cannot have
`const' method qualifier|
F:\CodeBlocksProject\listApp\graduate.h||In member function
`std::istream& graduate::getfrom(std::istream&) const':|
F:\CodeBlocksProject\listApp\graduate.h|63|error: request for member
`name' in `this', which is of non-class type `const graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h|65|error: request for member
`degree' in `this', which is of non-class type `const graduate*
const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function `bool
graduate::isEqual(const graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|77|error: request for member
`name' in `this', which is of non-class type `graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function
`std::eek:stream& graduate::sendto(std::eek:stream&) const':|
F:\CodeBlocksProject\listApp\graduate.h|86|error: request for member
`name' in `this', which is of non-class type `const graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h|86|error: request for member
`degree' in `this', which is of non-class type `const graduate*
const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function `bool
graduate::lessThan(const graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|95|error: request for member
`name' in `this', which is of non-class type `graduate* const'|
||=== Build finished: 10 errors, 0 warnings ===|

Could anybody here help ?
Thanks and best regards,
Sam
 
B

Bart van Ingen Schenau

Dir Sirs,

This is just a question from a C++ newbie regarding the operator
overloading.Since I do not want to use friend key word,I write class
graduate as below:

//graduate.h
#ifndef GRADUATE_H
#define GRADUATE_H

#include <iostream>
#include <string>

using namespace std;

class graduate
{
    public:
        /** Default constructor */
        graduate();
        string getDegree() const;
        bool isEqual(const graduate& rhs);
        bool lessThan(const graduate& rhs);
These two member functions should be declared as const, because they
will not modify *this.
        istream& getfrom(istream& istr)const;
This member function must NOT be declared as const.
        ostream& sendto(ostream& ostr)const;

    protected:
As there are no protected members, you can leave this line out.
    private:
    string name;
    string degree;};

bool operator==(const graduate& lhs,graduate& rhs)

For symmetry, and because neither operand will get changed, you should
declare both parameters as const (reference).
{
    return lhs.isEqual(rhs);}

bool operator<(const graduate& lhs,graduate& rhs)

Same here.
{
    return lhs.lessThan(rhs);

}

istream& operator>>(istream& istr,const graduate& grad)const

Both consts here are an error.
The 'const graduate& grad' is an error, because you actually want to
change the object with the information you read from the stream.
The const at the end is an error, because your operator>> is not a
member function, and const in that position is only allowed for member
functions.
{
    return grad.getfrom(istr);}

ostream& operator<<(ostream& ostr,const graduate& grad)const

Same problem with the const at the end.
{
    return grad.sendto(ostr);}

graduate::graduate()
{
    //ctor}

/** @brief getDegree
  *
  * @todo: document this function
  */
string graduate::getDegree() const
{
    return degree;

}

/** @brief getfrom
  *
  * @todo: document this function
  */
istream & graduate::getfrom(istream& istr)const

As said before, this function should be non-const, because it changes
*this.
{
    char ch;
    istr>>this.name;

this is a pointer, so you need this->name to access the name member.
    istr>>ch;
    istr>>this.degree;
    return istr;

}
Could anybody here help ?
Thanks and best regards,
Sam

Bart v Ingen Schenau
 
A

Alan Woodland

Sam said:
Dir Sirs,

This is just a question from a C++ newbie regarding the operator
overloading.Since I do not want to use friend key word,I write class
graduate as below:

//graduate.h
#ifndef GRADUATE_H
#define GRADUATE_H

#include <iostream>
#include <string>

using namespace std;

class graduate
{
public:
/** Default constructor */
graduate();
string getDegree() const;
const string& getDegree() const;
bool isEqual(const graduate& rhs);
bool isEqual(const graduate& rhs) const ;
bool lessThan(const graduate& rhs);
bool lessThan(const graduate& rhs) const;
istream& getfrom(istream& istr)const;
ostream& sendto(ostream& ostr)const;

protected:
private:
string name;
string degree;
};
bool operator==(const graduate& lhs,graduate& rhs)
{
return lhs.isEqual(rhs);
}
bool operator<(const graduate& lhs,graduate& rhs)
{
return lhs.lessThan(rhs);

}
istream& operator>>(istream& istr,const graduate& grad)const
istream& operator>>(istream& istr,const graduate& grad)
{
return grad.getfrom(istr);
}
ostream& operator<<(ostream& ostr,const graduate& grad)const
ostream& operator<<(ostream& ostr,const graduate& grad)
{
return grad.sendto(ostr);
}
graduate::graduate()
{
//ctor
}
/** @brief getDegree
*
* @todo: document this function
*/
string graduate::getDegree() const
const string& graduate::getDegree() const
{
return degree;
}

/** @brief getfrom
*
* @todo: document this function
*/
istream & graduate::getfrom(istream& istr)const
{
char ch;
istr>>this.name; istr >> this->name
istr>>ch;
istr>>this.degree;
istr>>this->degree

(Note also you should check that this has actually worked too!)
return istr;


}

/** @brief isEqual
*
* @todo: document this function
*/
bool graduate::isEqual(const graduate& rhs)
bool graduate::isEqual(const graduate& rhs) const
{
return this.name==rhs.name; return this->name==rhs.name;
}

/** @brief sendto
*
* @todo: document this function
*/
ostream & graduate::sendto(ostream& ostr)const
{
ostr<<"Name:"<< this.name<<"\tdegree:"<<this.degree<<endl;
ostr said:
return ostr;
}
/** @brief lessThan
*
* @todo: document this function
*/
bool graduate::lessThan(const graduate& rhs)
bool graduate::lessThan(const graduate& rhs) const
{
return this.name<rhs.name;
return this->name said:
}



#endif // GRADUATE_H
//end of graduate.h
Compiler generates a lot of error message:
F:\CodeBlocksProject\listApp\graduate.h||In function `bool operator==
(const graduate&, graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|28|error: passing `const
graduate' as `this' argument of `bool graduate::isEqual(const
graduate&)' discards qualifiers|
F:\CodeBlocksProject\listApp\graduate.h||In function `bool operator<
(const graduate&, graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|32|error: passing `const
graduate' as `this' argument of `bool graduate::lessThan(const
graduate&)' discards qualifiers|
F:\CodeBlocksProject\listApp\graduate.h|36|error: non-member function
`std::istream& operator>>(std::istream&, const graduate&)' cannot have
`const' method qualifier|
F:\CodeBlocksProject\listApp\graduate.h|40|error: non-member function
`std::eek:stream& operator<<(std::eek:stream&, const graduate&)' cannot have
`const' method qualifier|
F:\CodeBlocksProject\listApp\graduate.h||In member function
`std::istream& graduate::getfrom(std::istream&) const':|
F:\CodeBlocksProject\listApp\graduate.h|63|error: request for member
`name' in `this', which is of non-class type `const graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h|65|error: request for member
`degree' in `this', which is of non-class type `const graduate*
const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function `bool
graduate::isEqual(const graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|77|error: request for member
`name' in `this', which is of non-class type `graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function
`std::eek:stream& graduate::sendto(std::eek:stream&) const':|
F:\CodeBlocksProject\listApp\graduate.h|86|error: request for member
`name' in `this', which is of non-class type `const graduate* const'|
F:\CodeBlocksProject\listApp\graduate.h|86|error: request for member
`degree' in `this', which is of non-class type `const graduate*
const'|
F:\CodeBlocksProject\listApp\graduate.h||In member function `bool
graduate::lessThan(const graduate&)':|
F:\CodeBlocksProject\listApp\graduate.h|95|error: request for member
`name' in `this', which is of non-class type `graduate* const'|
||=== Build finished: 10 errors, 0 warnings ===|
I think that's all of them, haven't actually compiled it though.

You could just make the operator== and operator< member functions though.

Alan
 
S

Sam Hu

Thank you so much for all your help,both!And now I have a better
understanding how come C++ is called the most complicated language in
the world!!And here I have one more questions:why we need both const &
non-const version ,and under what situation these 2 are mandatory and
what situation we can just pick one of the 2?
bool isEqual(const graduate& rhs) const ;
        bool lessThan(const graduate& rhs);

Thanks and best regards,
Sam
 
Joined
Mar 27, 2009
Messages
8
Reaction score
0
Sam Hu said:
Thank you so much for all your help,both!And now I have a better
understanding how come C++ is called the most complicated language in
the world!!And here I have one more questions:why we need both const &
non-const version ,and under what situation these 2 are mandatory and
what situation we can just pick one of the 2?
> bool isEqual(const graduate& rhs) const ;
> * * * * bool lessThan(const graduate& rhs);


Thanks and best regards,
Sam

It's actually kinda simple - once you understand what the "const" at the end of the memberfunction declaration is.

A member function is a function that "belongs" to a specific instance of the class - that's a big way to say that by writing "a.isEqual(rhs)" the function "isEqual" has access to both "a" and "rhs". You actually have two input parameters.

As with all input parameters - you need to say say is they are const or not. "rhs" is easy - since you explicitly wrote it as an input in the declaration "bool isEqual(const graduate &rhs)". for the other input - you add "const" at the end of the declaration if you want it to be const "bool isEqual(const graduate &rhs) const".

Why would you need two versions? well, if your member function has to be (even slightly) different for a const or non-const instance, you need to write two functions - one const and another non-const.

Example time:
class foo{
public:
int &ref() // only need this if you want to be able to change "data".
// Because it returns a reference to "data", the compiler won't allow
// it for a const instance (cuz it allows you to change that "const" data)
{
cout << "non-const version"<<endl;
return data;
}
const int &ref() const
// since the return value is const reference, you can't use this to
// change "data". Hence the compiler will allow it for a const instance.
{
cout << "const version"<<endl;
return data;
}
private:
int data;
};

int main()
{
const foo C;
foo nC;

int a,b;
a=C.ref(); //leagal - runs the const version
b=nC.ref(); // legal - runs the non-const version
// C.ref()=5; // illegal - because C.ref() returns a "const int&" for a const instance, so it can't be changed
nC.ref()=7; // legal - because nC.ref() returns "int &" which can be changed.
return 0;
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top