Why I can't create or overload operator := in my class in C++?
Is there are some list operators that I can overload?
I can only overload, or also create some new custom operators?
Because no such operator exists in C++. You cannot roll your own operators because you would need to modify the grammar of the language for the parser to recognize them.
You can find a list of the available operators here or here (or better yet by reading the standard if you can get a copy).
Finally, be advised that overloading operators like there is no tomorrow is a mistake that pretty much every C++ beginner makes; operators are really nothing more than functions, and unless there is a very good case to be made for overloading an operator most of the time it's a better idea to just write a plain function for your class instead. For example, std::string does not have an operator* even though it could be argued that it's convenient to write
string sleepy = string("z") * 40;
The operators you can overload are:
Perhaps you meant the assignment or the equals operator.
class Object{
public:
///Overload The Assignment Operator
Object& operator=(const Object& objectIn);
///Overload The Equals Operator
bool operator == (const Object & rhs) const;
protected:
private:
};
Related
I've got these instructions for an assignment that have put me through a loop here. I need to overload the insertion operator to print out an objects datamembers. However, it states that the overloader has to be a non-friend helper operator.
If that's the case, how can it ever access the private datamembers if its not a 'friend'? And if this is possible, why should I avoid using 'friend'?
Here is what it says word for word:
a helper non-friend operator that inserts the stored string into the left ostream operand.
This operator prefaces the string with the number of the insertion and increment that number
I'm somewhat new to C++ so I really appreciate the help.
If it's not a friend, it needs to use the object's public interface (ergo, you need to write the object's public interface to include the access required by the insertion operator).
For example, you might do something like this:
class thing {
std::string name;
public:
std::string get_name() const { return name; }
// ...
};
std::ostream &operator<<(std::ostream &os, thing const &t) {
return os << t.get_name();
}
Note that I'm definitely not recommending this as good practice--rather the contrary, I think it's often a better idea for the insertion operator to be a friend. But if you're in a class and you're prohibited from doing things the right way, you do what you have to...
Following is the abstraction of string class.
class string {
public:
string(int n = 0) : buf(new char[n + 1]) { buf[0] = '\0'; }
string(const char *);
string(const string &);
~string() { delete [] buf; }
char *getBuf() const;
void setBuf(const char *);
string & operator=(const string &);
string operator+(const string &);
string operator+(const char *);
private:
char *buf;
};
string operator+(const char *, const string &);
std::ostream& operator<<(std::ostream&, const string&);
I want to know why these two operator overloaded functions
string operator+(const char *, const string &);
std::ostream& operator<<(std::ostream&, const string&);
are not class member function or friend functions? I know the two parameter operator overloaded functions are generally friend functions (I am not sure, I would appreciate if you could enlighten on this too) however my prof did not declare them as friend too. Following are the definitions of these function.
string operator+(const char* s, const string& rhs) {
string temp(s);
temp = temp + rhs;
return temp;
}
std::ostream& operator<<(std::ostream& out, const string& s) {
return out << s.getBuf();
}
Could anyone explain this with a small example, or direct me to similar question. Thanks in Advance.
Regards
The friend keyword grants access to the protected and private members of a class. It is not used in your example because those functions don't need to use the internals of string; the public interface is sufficient.
friend functions are never members of a class, even when defined inside class {} scope. This is a rather confusing. Sometimes friend is used as a trick to define a non-member function inside the class {} braces. But in your example, there is nothing special going on, just two functions. And the functions happen to be operator overloads.
It is poor style to define some operator+ overloads as members, and one as a non-member. The interface would be improved by making all of them non-members. Different type conversion rules are applied to a left-hand-side argument that becomes this inside the overload function, which can cause confusing bugs. So commutative operators usually should be non-members (friend or not).
Let's talk about operator +. Having it as a non member allows code such as the following
string s1 = "Hi";
string s2 = "There";
string s3;
s3 = s1 + s2;
s3 = s1 + "Hi";
s3 = "Hi" + s1;
The last assignment statement is not possible if operator+ is a member rather than a namespace scope function. But if it is a namespace scope function, the string literal "Hi" is converted into a temporary string object using the converting constructor "string(const char *);" and passed to operator+.
In your case, it was possible to manage without making this function a friend as you have accessors for the private member 'buf'. But usually, if such accessors are not provided for whatever reason, these namespace scope functions need to be declared as friends.
Let's now talk about operator <<.
This is the insertion operator defined for ostream objects. If they have to print objects of a user defined type, then the ostream class definition needs to be modified, which is not recommended.
Therefore, the operator is overloaded in the namespace scope.
In both the cases, there is a well known principle of Argument Dependent Lookup that is the core reason behind the lookup of these namespace scope functions, also called Koenig Lookup.
Another interesting read is the Namespace Interface Principle
Operators can be overloaded by member functions and by standalone (ordinary) functions. Whether the standalone overloading function is a friend or not is completely irrelevant. Friendship property has absolutely no relation to operator overloading.
When you use a standalone function, you might need direct access to "hidden" (private or protected) innards of the class, which is when you declare the function as friend. If you don't need this kind of privileged access (i.e. you can implement the required functionality in terms of public interface of the class), there's no need to declare the function as friend.
That's all there is to it.
Declaring a standalone overloading function as friend became so popular that people often call it "overloading by a friend function". This is really a misleading misnomer, since, as I said above, friendship per se has nothing to do with it.
Also, people sometimes declare overloading function as friend even if they don't need privileged access to the class. They do it because a friend function declaration can incorporate immediate inline definition of the function right inside the class definition. Without friend one'd be forced to do a separate declaration and a separate definition. A compact inline definition might just look "cleaner" in some cases.
I'm a bit rusty with C++ overloads but I would complete the above answers by this simple memo :
If the type of the left-hand operand is a user-defined type (a class, for instance), you should (but you don't have to) implement the operator overloading as a member function. And keep in mind that if these overloads -- which will most likely be like +, +=, ++... -- modify the left-hand operand, they return a reference on the calling type (actually on the modified object). That is why, e.g. in Coplien's canonical form, the operator= overloading is a member function and returns a "UserClassType &" (because actually the function returns *this).
If the type of the left-hand operand is a system type (int, ostream, etc...), you should implement the operator overloading as a standalone function.
By the way, I've always been told that friend keyword is bad, ugly and eats children. I guess it's mainly a matter of coding style, but I would therefore advice you to be careful when you use it, and avoid it when you can.
(I've never been faced to a situation where its use was mandatory yet, so I can't really tell ! )
(And sorry for my bad English I'm a bit rusty with it too)
Scy
I want to overload the "receiver" operator so I can do this: someClass >> myClass.
...where myClass is the class which I need to overload the operator for.
Hope that makes sense.
As #Mysticial pointed out, you need to overload operator>> to do this.
That overload can not be a member of myClass though. It must be either a member of someClass, or else a global overload.
class someClass {
// ...
someClass &operator>>(myClass &);
};
or:
someClass &operator>>(someClass &, myClass &);
If the operator doesn't/can't change the state of the someClass object, you might want to pass the first parameter by const reference (in which case you'd also return a const reference).
Of course, returning a someClass isn't really required, but it's the normally accepted practice for this kind of operator (it allows chaining the operators for something like a >> b >> c;)
>> is the operator. You want to overload operator>>. The signature will look like this:
someClass& operator>>(someClass&, myClass&);
You need to use argument-dependent lookup... I haven't used it myself very often, but you need to overload operator >> with ADL (see the link).
It's possible to overload the not operator for a class:
class TestA
{
public:
bool Test;
const bool operator!(){return !Test;}
};
So that...
TestA A; A.Test = false;
if(!TestA){ //etc }
...can work. However, how does the following work?
if(TestA) //Does this have to be overloaded too, or is it the not operator inverted?
I will add, having read it, I am slightly confused by the typedef solution that is employed, and I don't fully understand what is occurring, as it seems somewhat obsfucated. Could someone break it down into an understandable format for me?
You could write an operator bool(). This takes care of coercion to bool, making statements as your above one possible.
You overload operator void* (like the standard library's iostreams) or use boost's trick of using an "unspecified_bool_type" typedef (safe bool). It does NOT automatically invert your operator!
I have a class like this:
class A {
...private functions, variables, etc...
public:
...some public functions and variables...
A operator * (double);
A operator / (double);
A operator * (A);
...and lots of other operators
}
However, I want to also be able to do stuff like 2 * A instead of only being allowed to do A * 2, and so I would need functions like these outside of the class:
A operator * (double, A);
A operator / (double, A);
...etc...
Should I put all these operators outside of the class for consistency, or should I keep half inside and half outside?
IMHO, the concern shouldn't be with stylistic consistency, but with encapsulation consistency; generally if a function does not need access to private members, it should not be part of the class. This is not a hard an fast rule, see arguments for it here.
So if your operators do not require private access, put them all outside. Otherwise, they will all have to be inside like so:
class A {
...
public:
...
A operator * (double);
A operator / (double);
friend A operator * (double, A);
friend A operator / (double, A);
...
};
From your replies to comments in the question it seems that you have an implicit conversion from double to A in your class. something like:
class A
{
// ...
public:
A(double);
// ...
};
In this case you can simply define a free function for each operator of the form:
A operator*( const A&, const A& );
and it will be used if either side is an A object and the other side is implicitly convertible to an A. For this reason it is often preferable to make symmetric binary operators free functions.
Frequently it can be easier to implement binary * in terms of the assignment version *=. In this case I would make the assignment version a member function and define * as something like:
A operator*( const A& l, const A& r )
{
A result(l);
result += r;
return result;
}
Otherwise as operator* is plainly part of your class interface I would have no problem with making it a friend if required.
So what you are saying is that because you must put some operators (the ones that don't have A as the first param) outside the class, maybe you should put them all there so people know where to find them? I don't think so. I expect to find operators inside the class if at all possible. Certainly put the "outside" ones in the same file, that will help. And if the outside ones need access to private member variables, then adding the friend lines is a huge hint to look elsewhere in the file for those operators.
Would I go so far as to include the friend lines even if my implementation of the operators could actually be done with public getters and setters? I think I would. I think of those operators as really being part of the class. It's just that the language syntax requires them to be free functions. So generally I use friend and I write them as though they were member functions, not using getters and setters. It's a pleasant side effect that the resulting need for friend statements will cause them all to be listed in the definition of the class.