Overloaded '+' Operator Not Compiling - c++

I'm trying to understand the concept of operator overloading by writing some simple, silly tests. I thought this might be useful as this helps me understand C++ better.
Why does this example implementing a concatenation operator of Animal class and std::string not compile? G++ gives me the following error:
extra qualification 'Animal::' on member 'operator+' [-fpermissive]
This is the code:
#include <iostream>
using namespace std;
class Animal {
public:
string _type;
string _name;
string _sound;
Animal & Animal::operator+(const string & o);
};
Animal & Animal::operator+(const string & o) {
cout << "plus operator \n";
this->_name=o;
return *this;
}
int main( int argc, char ** argv ) {
Animal a;
a+"hhh";
cout<<a._name;
return 0;
}

Animal & Animal::operator+(const string & o);
Is invalid. It should be:
Animal & operator+(const string & o);
Also, your implementation of a simple addition operator, results in the modifications of one of the operands. This is never a good thing for an addition operator.
For example:
int a, b = 5, c = 3;
a = b + c;
That doesn't change the values of either operands; it leaves b and c untouched, and returns an entirely different instance.
You should therefore not overload the addition operator, but the addition assignment compound operator (+=):
Animal & operator+=(const string & o);
And of course change the implementation and calls to it accordingly:
Animal & Animal::operator+=(const string & o) {
cout << "plus operator \n";
this->_name=o;
return *this;
}
And:
a += "hhh";

The declaration of operator+ inside your class does not need to be qualified, precisely because it is being declared within the class:
class Animal {
// ...
Animal& operator+(const string& o);
}
This qualification is necessary when you define the function because you define it outside the class - the compiler needs to know to which class the function belongs.

There's no need for the Animal:: in the prototype, because it's inside the Animal class already. Just use:
Animal & operator+(const string & o);

The Animal:: qualification should be used in the definition of a member function, not in the declaration. Thus, change your operator declaration into:
Animal & operator+(const string & o);

Related

istream overloading with 2nd argument being a double pointer?

My question is what is the proper way to implement this, and how exactly would I make use of it?
The operator to be overloaded has the following prototype:
//Reads a variable from an input stream
//A variable should have a one-word name that does not start with a digit or minus sign
istream& operator>>(istream& in, Variable** v)
We are given a variable class along with an equation class. I think the goal of overloading the istream operator is to make things easier when creating an equation object from a string. You can find it below.
My attempt at implementing this is as follows:
istream& operator>>(istream& in, Variable** v)
{
string i;
in >> i;
if (isalpha(i[0]) && i[0] != '-')
*v = new Variable(i);
return in;
}
Variable Class:
class Variable : public Operand
{
private:
static unordered_map<string, int> vars;
string name;
public:
Variable(string);
virtual int getValue() const override;
void setValue(int);
};
Equation class:
class Equation
{
private:
Variable* var;
Operand* lhs;
operator_t op;
Operand* rhs;
public:
Equation(string);
int evaluate();
//Should also implement copy constructor and copy assignment (rule of three)
~Equation();
};

virtual methods, operator=(), operator<<();

class Port
{
private:
char * brand;
char style[20]; // i.e., tawny, ruby, vintage
int bottles;
public:
Port(const char * br = "none", const char * st = "none", int b = 0);
Port(const Port & p); // copy constructor
virtual ~Port() {delete[] brand; }
Port & operator=(const Port & p);
Port & operator+=(int b); // adds b to bottles
Port & operator-=(int b); // subtracts b from bottles, if
int BottleCount() const { return bottles; }
virtual void Show() const;
friend ostream & operator<<(ostream & os, const Port & p);
};
class VintagePort : public Port // style necessarily = "vintage"
{
private:
char * nickname; // i.e., "The Noble" or "Old Velvet", etc.
int year; // vintage year
public:
VintagePort();
VintagePort(const char * br, const char *st, int b, const char * nn, int y);
VintagePort(const VintagePort & vp);
~VintagePort() { delete[]nickname;}
VintagePort & operator=(const VintagePort & vp);
virtual void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};
I have to explain why operator=() and operator<<() are not
virtual. I think that operator<<() can't be virtual because only class methods could be, but I have no idea about operator=(). How does the pointer at basic class know which one of operator=() it has to use?
Second question is about how I can make operator<<() behave like a virtual method for example:
basicClass B;
inheritClass I;
basicClass *ptr;
ptr=&I;
std::cout << ptr // Here I'd like to use operator<<(std::ostream, inheritClass)
operator = is not virtual because it is not marked virtual. The declaration of operator = looks like this
//No virtual here
Port& operator =(const Port&);
If, however, operator = was virtual it would be declared like this
virtual Port& operator =(const Port&);
^^^^^^^ Virtual here!
Since operator = is not virtual the compiler uses static linkage when compiling. This means the function called is dependent on the type of the variable it is being referred to by. Consider this code:
VintagePort vp;
//Calls VintagePort::operator =(const VintagePort&)
vp = VintagePort();
Port* p = &vp;
//Calls Port::operator =(const Port&)
*p = Port();
VintagePort::operator = is called when it is being accessed as a VintagePort, however, Port::operator = is called when it is accessed as a Port. (Live example here.)
To make operator << behave as if it were virtual you would have to declare a virtual member function within your class that does the printing. Something like this
//Inside Port
virtual void Print(std::ostream& os) const
{
os << brand << ' ' << style << ' ' << bottles;
}
Then in every class that derives from Port (like VintagePort) you would override the method to also print the values for that derived class. So for VintagePort you could do this
//Inside VintagePort
void Print(std::ostream& os) const
{
//Make Port print first
Port::Print(os);
os << ' ' << nickname << ' ' << year;
}
Then in operator << all you would have to do is to call the Print method on the argument. Which would look like this:
std::ostream& operator <<(std::ostream& os, const Port& p)
{
P.Print();
return os;
}
As a plus you don't have to overload operator << for every derived the class as the overload only needs the virtual function in the Port class.
This has the feeling of a codereview which is not what SO is for -- but anyways:
Don't use character arrays. Use std::string:
class Port
{
private:
std::string brand;
std::string style; // i.e., tawny, ruby, vintage
//...
};
Moreover, and in general, don't use pointers where objects are appropriate. And if you need pointers, use smart pointers to clearly express the purpose.
This is the RAII principle which underpins most of C++.
If you follow the previous suggestion, there is no need to define: destructors, copy/move constructors, and -- that touches your question -- also not assignment operators. (And particularly, there is no need to overload the latter).
operator<< can't should not declared virtual, as it is not a class member. It's a stand-alone function which, due to being a friend, may have access to private members of your port wine classes.
But you can overload it outside of the class. This is what one straightforwardly does by setting up different overloads as operator<<(ostream & os, const Port & p); and operator<<(ostream & os, const VintagePort & p);.

When is the internal operator being used and when the external

Let's say I have defined a class with an internal + operator and also an external + operator;
class MyClass {
public:
MyClass operator +();
};
MyClass operator +(const MyClass& a);
If in my main program I call
MyClass a;
MyClass b = +a;
What is being called, this (internal):
a.operator +()
or this (external)?:
operator +(a)
The same question for binary operators.
The member function is chosen: it can bind directly to the expression a, while the non-member function needs to convert MyClass to const MyClass before binding to the reference parameter. So calling the member involves a better conversion sequence, making that the best overload.
If you removed const from the non-member, or added const to the member, then both would be equally viable; you should get an error saying that the overload is ambiguous.
By fixing some ambiguities in the code, and doing some printing, the following code will give the answer Internal operator.
class MyClass {
public:
MyClass operator+() {
std::cout << "Internal operator." << std::endl;
return *this;
};
};
MyClass operator+(const MyClass& a) {
std::cout << "External operator" << std::endl;
return a;
}
int main() {
MyClass a, b;
b = +a;
return 0;
}
The internal operator is used because you cannot overload an operator with the same arguments once it already exists: you cannot define a + operator for strings that does something crazy because there already is one that concatenates them. That's the same case. You have a + operator defined inside the class, so the identical one( as function prototype ) becomes useless.
I did a little test myself:
#include <iostream>
#include "MyClass.h"
using namespace std;
MyClass operator +(const MyClass& a, const MyClass& b)
{ cout << "external" << endl; return a; }
int main() {
MyClass foo, bar;
foo + bar;
return 0;
}
class MyClass {
public:
MyClass operator+(const MyClass& a) { cout << "internal" << endl; return a; }
};
The output of the program was "internal".
My conclusion is that if there is an internal operator that fits the operation it will be the one taken. I can't see a way to make the external one to be taken if the internal fits better. But I must point out that I only did a little test and haven't learned somewhere that this is the 100% answer.

C++ how to write an operator that isn't a member function?

Anyone got an idea on how to write an operator for a class that isn't a member function of the class?
Just make it a free function, or a friend function. A good example of this is operator<<:
class X {
public:
int x;
}
ostream& operator<< (ostream& os, const X& x) {
os << x.x;
return os;
}
The benefit of making it a friend function is that you have direct access to private members, whereas a free function must access all members via public methods.
Arithmetic operators, stream operators, et cetera are often not members of a class. However, they may need to be friends in order to access private data members.
I prefer not to use friend and to expose methods that can be used by the operators instead. I believe this to be more in keeping with the Open/closed principle, as I could easily add a subtraction operator without editing the class.
These are handy for unit-testing, too (I can "inject" a std::ostringstream to test the output of print(), for instance).
Here is an example:
#include <iostream>
class Number
{
public:
Number(int j)
:i(j)
{
}
void print(std::ostream& os) const
{
os << i;
}
int value() const
{
return i;
}
private:
int i;
};
std::ostream& operator <<(std::ostream& os, const Number& n)
{
n.print(os);
return os;
}
Number operator +(const Number& n, const Number& o)
{
return Number(n.value() + o.value());
}
int main()
{
Number a(4), b(5), c(a + b);
std::cerr << c << std::endl;
}
Just declare the global function with the operator name:
Point operator+(Point& p, Vector& v) {
return new Point(p.x + q.i, p.y + q.j);
}
Basically, you can take the operator out of the class, and add a parameter to the beginning of the parameter list. In many cases, you will also need to declare the operator function as a friend.
For instance
class Foo
{
Foo operator +( Foo const& other );
};
becomes
class Foo
{
friend Foo operator +( Foo const&, Foo const& );
};
Foo operator +( Foo const& first, Foo const& second );
The friend statement allows the operator to still access any private or protected members needed.
Note that there are some restrictions on which operators can be overloaded in this manner. See this article for such a list.

'friend' functions and << operator overloading: What is the proper way to overload an operator for a class?

In a project I'm working on, I have a Score class, defined below in score.h. I am trying to overload it so, when a << operation is performed on it, _points + " " + _name is printed.
Here's what I tried to do:
ostream & Score::operator<< (ostream & os, Score right)
{
os << right.getPoints() << " " << right.scoreGetName();
return os;
}
Here are the errors returned:
score.h(30) : error C2804: binary 'operator <<' has too many parameters
(This error appears 4 times, actually)
I managed to get it working by declaring the overload as a friend function:
friend ostream & operator<< (ostream & os, Score right);
And removing the Score:: from the function declaration in score.cpp (effectively not declaring it as a member).
Why does this work, yet the former piece of code doesn't?
Thanks for your time!
EDIT
I deleted all mentions to the overload on the header file... yet I get the following (and only) error. binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion)
How come my test, in main(), can't find the appropriate overload? (it's not the includes, I checked)
Below is the full score.h
#ifndef SCORE_H_
#define SCORE_H_
#include <string>
#include <iostream>
#include <iostream>
using std::string;
using std::ostream;
class Score
{
public:
Score(string name);
Score();
virtual ~Score();
void addPoints(int n);
string scoreGetName() const;
int getPoints() const;
void scoreSetName(string name);
bool operator>(const Score right) const;
private:
string _name;
int _points;
};
#endif
Note: You might want to look at the operator overloading FAQ.
Binary operators can either be members of their left-hand argument's class or free functions. (Some operators, like assignment, must be members.) Since the stream operators' left-hand argument is a stream, stream operators either have to be members of the stream class or free functions. The canonical way to implement operator<< for any type is this:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// stream obj's data into os
return os;
}
Note that it is not a member function. Also note that it takes the object to stream per const reference. That's because you don't want to copy the object in order to stream it and you don't want the streaming to alter it either.
Sometimes you want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming
class T {
public:
void stream_to(std::ostream&) const {os << obj.data_;}
private:
int data_;
};
and call that from the operator:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
or make the operator a friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
so that it can access the class' private parts:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
Let's say you wanted to write an operator overload for + so you could add two Score objects to each other, and another so you could add an int to a Score, and a third so you could add a Score to an int. The ones where a Score is the first parameter can be member functions of Score. But the one where an int is the first parameter can't become member functions of int, right? To help you with that, you're allowed to write them as free functions. That is what is happening with this << operator, you can't add a member function to ostream so you write a free function. That's what it means when you take away the Score:: part.
Now why does it have to be a friend? It doesn't. You're only calling public methods (getPoints and scoreGetName). You see lots of friend operators because they like to talk directly to the private variables. It's ok by me to do that, because they are written and maintained by the person maintaing the class. Just don't get the friend part muddled up with the member-function-vs-free-function part.
You're getting compilation errors when operator<< is a member function in the example because you're creating an operator<< that takes a Score as the first parameter (the object the method's being called on), and then giving it an extra parameter at the end.
When you're calling a binary operator that's declared as a member function, the left side of the expression is the object the method's being called on. e.g. a + b might works like this:
A a;
B b
a.operator+(b)
It's typically preferable to use non-member binary operators (and in some cases -- e.g. operator<<for ostream is the only way to do it. In that case, a + b might work like this:
A a;
B b
operator+(a, b);
Here's a full example showing both ways of doing it; main() will output '55' three times:
#include <iostream>
struct B
{
B(int b) : value(b) {}
int value;
};
struct A
{
A(int a) : value(a) {}
int value;
int operator+(const B& b)
{
return this->value + b.value;
}
};
int operator+(const A& a, const B& b)
{
return a.value + b.value;
}
int main(int argc, char** argv)
{
A a(22);
B b(33);
std::cout << a + b << std::endl;
std::cout << operator+(a, b) << std::endl;
std::cout << a.operator+(b) << std::endl;
return 0;
}