Operator +/- overloading as a non member function in C++ - c++

So I have written some code that implements this hierarchy:
class A
{
int x;
int y;
public:
A () { }
void setX(int x) { this->x = x;}
void setY(int y) { this->y = y;}
int getX(void) { return x;}
int getY(void) { return y;}
virtual int somefunc() = 0;
friend B operator- ( B b1, B b2);
};
class B : public A
{
int somefunc() {return 0;}
};
class C : public A
{
int somefunc() {return 1;}
};
class D : public C
{
int somefunc() {return 2;}
};
/*
// 1 st attempt - fail
A operator- (const A& a_inst, const A& a_inst2)
{
A a_temp;
a_temp.setX( a_inst.getX() - a_inst2.getX() );
a_temp.setY( a_inst.getY() - a_inst2.getY() );
return a_temp;
}
// 2nd attempt - FAIL
const A* operator- (const A* a1, const A* a2)
{
a1.setX( a1.getX() - a2.getX() );
a1.setY( a1.getY() - a2.getY() );
return a1;
}
//*/
//3rd attempt
B operator- ( B b1, B b2)
{
int temp1x = b1.getX();
int temp2x = b2.getX();
b1.setX( temp1x - temp2x );
int temp1y = b1.getY();
int temp2y = b2.getY();
b2.setY( temp1y - temp2y );
return b1;
}
int main()
{
B b();
C c();
b = b - dynamic_cast<B*>(c) ;
}
I understand that since A is an abstract class it can't be instantiated, so I can't do it with Class A instances.
Is it possible to overload both +/- once (each) and make it apply for every instance that belongs to a class in this hierarchy? Also I want to point out that I want to be able to do the same thing with objects of different classes at the same time like so:
C c;
B b;
b = b - c;
EDIT 1~ added a second version of the overloading that I am currently trying to get to work.
EDIT 2~ Corrected mistaken call of setters
EDIT 3~ added a 3rd version, still getting errors

There are some problems in you code:
1. You should specify the inheritance type: public
class B : public A {
...
}
2. B operator- (const B& a_inst, const B& a_inst2)
{
B a_temp;
a_temp.setX() = a.getX() - a_inst2.getX();
a_temp.setY() = a.getY() - a_inst2.getY();
return a_temp;
}
You can't use like that, since setX and setY returns value not pointer or reference.

Related

How to code operation overload so it operates to a specific class member such as A<<{{1,2,3},{5,6,7}} in c++?

You can redefine operator << in class by overload it.
However, how do you code it so that it would operates specific to a certain class member?
for example
class C
{
int a;
double b;
}
// I would like something like
void main ()
{
C c;
c.a << 1; // sets class member a to value 1;
}
I want a operator defined in Class C that operates specifically to class member a.
a pesudo-code would be
class C
{
int a;
double b;
void operator << (istream & fin)
{
... fin.get()... some code
}
}
Stating the obvious for a moment, assuming the variable is public, you'd use:
class C
{
int a;
double b;
}
// I would like something like
void main ()
{
C c;
c.a = 1; // sets class member a to value 1;
}
The << and >> operators are bit shifts, which have their own meaning. Overloading those for your own purpose is probably a bad idea.
The C++ way of doing things is to avoid setting member variables externally where possible (e.g. using RAII approaches, to set data at initialisation)....
class C
{
public:
C(int a, double b) : a(a), b(b) {}
int getA() const { return a; }
double getB() const { return b; }
private:
int a;
double b;
};
.... Or by adding a setter method if you really need it, e.g.
class C
{
public:
C(int a, double b) : a(a), b(b) {}
int getA() const { return a; }
double getB() const { return b; }
void setA(int v) { a = v; }
void setB(double v) { b = v; }
private:
int a;
double b;
};
You could in theory generate a new type, and overload the operators for that type, but it's not something I'd recommend (because changing the meaning of an operator is almost always a bad idea)
struct MyIntType {
int i;
// overload cast operator
operator int () {
return i;
}
// assign
MyIntType& operator = (const int& v) {
i = v;
return *this;
}
// not recommended :(
MyIntType& operator << (const int& v) {
i = v;
return *this;
}
};
class C
{
public:
MyIntType a;
double b;
};
void main ()
{
C c;
c.a << 1;
}
Having read your comment above, it sounds like you want to do this:
class C
{
public:
// I'm still not recommending this :(
C& operator << (const int& v) {
a = v;
return *this;
}
private:
int a;
double b;
};
void main ()
{
C c;
c << 1; //< now sets c.a
}

Mocking a non-virtual function using Google Mock?

I am trying to mock the function sub so that I can test the function add.I am using non-virtual function,
//Non_virtual function
class baseclass {
public:
int add(int a, int b) {
return (a + sub(a, b));
}
int sub(int c, int d) {
return (c - d);
}
};
class mockclass {
public:
MOCK_METHOD2(sub, int(int a, int b));
};
TEST(sample_test, testmain) {
mockclass mo;
int c = 12;
int d = 4;
EXPECT_CALL(mo, sub(c, d))
.WillOnce(testing::Return(8));
EXPECT_EQ(mo.add(c, d), 20);
}
I don't know how to make the relationship between the add and sub and don't know where I was making mistake.
I can do it with virtual function but I want to do it in non-virtual function.
Thanks in advance
Possible way without virtual:
struct MySub
{
int sub(int c, int d) const { return c - d; }
};
template <typename Sub>
class baseclassT : public Sub
{
public:
int add(int a, int b) {
return (a + this->sub(a, b));
}
};
using baseclass = baseclassT<MySub>; // For prod
And then, for test:
class MockSub {
public:
MOCK_METHOD2(sub, int(int a, int b));
};
TEST(sample_test, testmain)
{
baseclassT<MockSub> mo;
int c = 12;
int d = 4;
EXPECT_CALL(mo, sub(c, d)).WillOnce(testing::Return(8));
EXPECT_EQ(mo.add(c, d), 20);
}

assignments operator between father and son

I have the next classes.
in the main I have 2 kinds of assignments operator (A=A and B=B).
I'm trying to get the main working, so I tried:
class A { // assume that this class is abstract
public:
virtual void assignment(const A& num) = 0;
void operator=(const A& num) { assignment(num); }
void func() = 0; // the class is abstract
};
class B: public A {
int i;
public:
void assignment(const B& num) { i = num.i; }
B& operator=(const B& num) { i = num.i; }
void func() { cout << "hello!\n"; }
};
int main()
A* a1 = new B(7); //assume I have it
A* a2 = new B(6); //assume I have it
B b1(2);
B b2(4);
*a1 = *a2; // implement an assignment operator
b1 = b2; // implement an assignment operator
}
but I got some errors that tell me that B is an abstract class and then the copy constructor doesn't work
any help appreciated!
Ok, now I see what the problem is:
void assignment(const B& num) { i = num.i; }
should be:
void assignment(const A& num) { ... }
However, we now have a problem: num which is of type A does not have a member variable i. So we need to ensure that num is actually of class B. The ... part in the above now turns into:
B& b_num = dynamic_cast<B&>(num);
i = num.i;
Note however that dynamic_cast may throw an exception if you are trying to convert some other type to B& than B.

How to get rid of the ugly record

class c {
private:
int n[10];
public:
c();
~c();
int operator()(int i) { return n[i];};
};
class cc {
private:
public:
c *mass;
cc();
~cc();
c& operator*() const {return *mass;};
};
int somfunc() {
c *c1 = new c();
cc * cc1 = new cc();
(*cc1->mass)(1);
delete c1;
}
I've got a pointer into class cc to class c.
Is there any way to get rid of record like this:
(*cc1->mass)(1);
and write somethink like that:
cc1->mass(1);
is it impossible?
When I saw the tags "c++" and "operator overloading", my mind alarm turns ON.
C++ operator overloading is complex, and some operators like "()" or "->" make it more difficult.
I suggest, before overloading operators, making either a global function or method with the same purpouse, test it works, and later replace it with the operator.
Global friend function example:
class c {
private:
int n[10];
public:
c();
~c();
// int operator()(int i) { return n[i]; }
// there is a friend global function, that when receives a "c" object,
// as a parameter, or declares a "c" object, as a local variable,
// this function, will have access to the "public" members of "c" objects,
// the "thisref" will be removed, when turned into a method
friend int c_subscript(c thisref, int i) ;
};
int c_subscript(c* thisref, int i)
{
return c->n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c_subscript(objC, 3);
// do something with "x"
return 0;
} // int main(...)
Local function ( "method" ) example:
class c {
private:
int n[10];
public:
c();
~c();
// int operator()(int i) { return n[i]; }
int subscript(int i) ;
};
int c::subscript(int i)
{
return this.n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c->subscript(objC, 3);
// do something with "x"
return 0;
} // int main(...)
And, finally use the overloaded operator:
class c {
private:
int n[10];
public:
c();
~c();
int subscript(int i) ;
int operator()(int i) { return this.subscript(i); }
};
int c::subscript(int i)
{
return this.n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c->subscript(3);
// do something with "x"
int x = c(3);
// do something with "x"
return 0;
} // int main(...)
Note that in the final example, I keep the method with a unique identifier.
Cheers.
Could always do this:
class cc {
private:
c *_mass;
public:
c& mass() const {return *_mass;};
};
Now..
cc1->mass()(1);
If mass were an object, not a pointer, you could use the syntax you want:
class cc {
private:
public:
c mass;
cc();
~cc();
const c& operator*() const {return mass;};
};
…
cc1->mass(1);
You can with
(*(*cc1))(1)
because operator() is applied to an object, not a pointer.
You can use
(**cc1)(1);
Or
cc1->mass->operator()(1);

what is the difference between overloading an operator inside or outside a class?

In C++, i know there are two ways to overload. We can overload it inside (like class a) or outside (like class b). But, the question is, is there any difference between these two either in compile time or runtime or not?
class a
{
public:
int x;
a operator+(a p) // operator is overloaded inside class
{
a temp;
temp.x = x;
temp.x = p.x;
return temp;
}
};
class b
{
public:
friend b operator+(b, b);
int x;
};
b operator+(b p1, b p2) // operator is overloaded outside class
{
p1.x += p2.x;
return p1;
}
The member operator+ requires the LHS to be an a - The free operator requires LHS or RHS to be a b and the other side to be convertible to b
struct Foo {
Foo() {}
Foo(int) {}
Foo operator+(Foo const & R) { return Foo(); }
};
struct Bar {
Bar() {}
Bar(int) {}
};
Bar operator+(Bar const & L, Bar const & R) {
return Bar();
}
int main() {
Foo f;
f+1; // Will work - the int converts to Foo
1+f; // Won't work - no matching operator
Bar b;
b+1; // Will work - the int converts to Bar
1+b; // Will work, the int converts to a Bar for use in operator+
}