non member += overloading in C++ - c++

#include <iostream>
class A
{
public:
int a;
A() { a = 2;}
A(int f) { a= f;}
void print() { std::cout << a << std::endl; }
};
class B
{
A a, at, at2;
A& operator += (A& b)
{
a.a = a.a + b.a;
return a;
}
public:
B(int a_, int at_, int at2_) : a(a_), at(at_), at2(at2_) {};
void update ()
{
a += at;
}
void printAll() { a.print(); at.print();}
};
int main()
{
B value ( 2, 3, 5);
value.printAll();
value.update();
value.printAll();
}
The error is :
temp.cpp:24:10: error: no match for 'operator+=' in '((B*)this)->B::a += ((B*)this)->B::at'
What am I doing wrong ?

The operator you are defining is A & operator+=(B &, A & ), not A & operator+=(A &, A &). So you have defined how to add an A to a B, but not how to add an A to an A. Try this after the definition of class A but before that of class B:
A & operator+=(A & a1, const A & a2) { a1.a += a2.a; return a1; }
But this kind of operator is more natural to define as a member function.

A& B::operator += (A& b)
Means
A & operator+=(B &, A & )
You simply need to add operator +=(const A&b) to class A
class A
{
//....
A& operator += (const A& b)
{
a += b.a;
return *this;
}
//....
};
A non-member version is:
A & operator+=(A a1, const A & a2) { a1.a += a2.a; return a1; }

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
}

Architecture pattern: function to handle 2 identical implementations

I have the following problem which I guess I am solving incorrectly given the problem I am facing:
I have an interface I and implementations A, B, C... I want to somehow express that I can get some results from couples (f(A, A), f(B, B), f(C, C)) and so on. In other words, I want to interface I to express that 2 identical implementations can be combined to produce some results, while others can be not (you can't get any valid result from f(A, B)).
Right now I have the following:
#include <iostream>
using namespace std;
class A;
class B;
class I{
public:
virtual int f (const I &other) const = 0;
virtual int fSpecific (const A &other) const { throw runtime_error(""); };
virtual int fSpecific (const B &other) const { throw runtime_error(""); };
};
class A: public I{
public:
A(int a) : a(a) {}
int f (const I &other) const override { other.fSpecific(*this); }
int fSpecific (const A &other) const override { /*logic here*/ return a + other.a; }
int a;
};
class B: public I{
public:
B(int b1, int b2) : b1(b1), b2(b2) {}
int f (const I &other) const override { other.fSpecific(*this); }
int fSpecific (const B &other) const override { /*logic here*/ return b1*b1 + b2*b2 + other.b1*other.b1 + other.b2*other.b2; }
private:
int b1;
int b2;
};
int f(const I &a, const I &b) {
a.f(b);
}
int main()
{
cout << f(A(1), A(2)) << std::endl; // prints 3
cout << f(B(1, 2), B(3, 4)) << std::endl; // prints 30
cout << f(A(1), B(3, 4)) << std::endl; // throws an error
return 0;
}
/*and so on*/
But I guess I use a wrong architecture. as adding classes results in changing I. Are there any better solution to express this such a relation?
Your interface is indeed strange, asking for method which should not be implemented.
We don't have multiple dynamic dispatch, except with std::visit of std::variant.
So following might help:
using V = std::variant<A, B, C>;
int f(const V& v1, const V& v2) {
struct {
template <typename T1, typename T2>
int operator()(const T& t1, const T2& t2) const { throw runtime_error(""); };
int operator()(const A& a1, const A& a2) const { return a1.a + a2.a; };
int operator()(const B& b1, const B& b2) const { return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2; };
int operator()(const C& c1, const C& c2) const { return c1.c * c2.c; };
} visitor;
return std::visit(visitor, v1, v2);
}
or keeping you hierarchy:
using CV = std::variant<const A*, const B*, const C*>;
class I
{
public:
virtual ~I() = default;
virtual CV asVariant() const = 0;
};
class A: public I{
public:
A(int a) : a(a) {}
CV asVariant() const override { return this; }
friend int f (const A& a1, const A& a2) { /*logic here*/ return a1.a + a2.a; }
int a;
};
class B: public I{
public:
B(int b1, int b2) : b1(b1), b2(b2) {}
CV asVariant() const override { return this; }
friend int f (const B& b1, const B& b2) {
/*logic here*/ return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2;
}
private:
int b1;
int b2;
};
int f(const I& i1, const I& &2) {
struct {
template <typename T1, typename T2>
int operator()(const T1*, const T2*) const { throw runtime_error(""); };
template <typename T>
int operator()(const T* t1, const T* t2) const { return f(*t1, *t2); };
} visitor;
return std::visit(visitor, i1.AsVariant(), i2.AsVariant());
}
You may employ dynamic_cast:
class I {
public:
template<typename T>
void fSpecific (T &other) {
if (dynamic_cast<T*>(this))
std::cout << "OK" << std::endl;
else
std::cout << "ERROR" << std::endl;
}
virtual ~I() {}
};
class A : public I {
};
class B : public I {
};
int main()
{
A a;
a.fSpecific(a);
B b;
b.fSpecific(a);
b.fSpecific((I&)a);
return 0;
}
There are some problems however:
Multiple inheritance
Objects need to be dynamically castable (that is why I added a virtual interface)
Casting to I also works.

C++ - Deal with implicit/explicit casts while keeping flexible code

I am looking for a way to express interoperability between a class A and built-in integer types while keeping high flexibility in my code. E.g, I would like to be able to use operator & freely between (A and A), (A and int), (int and A) and (int and int), i.e. I want to have the result of x = y & z whether x, y and z are type class A or type int, just writing:
x = y & z;
The following code works:
#include <cstdlib>
#include <iostream>
class A {
public:
int x;
explicit A(int i) : x(i) {}
operator int() {
return this->x;
}
A operator &(const A& src) const {
return A(this->x & src.x);
}
};
int main() {
int b(2), b2(0), b3(0);
A a(3);
b2 = a & b;
b3 = b & a;
std::cout << b2 << std::endl;
std::cout << b3 << std::endl;
return 0;
}
However, if I add a new cast function from A to unsigned int in class A, this does not work any more because operator & is defined between (int and int) and also (int and unsigned int), so when I do:
b2 = a & b
the compiler doesn't know if a should be cast to int or unsigned int, which is logical. I see 2 possibilities to solve it:
Explicitely implementing operator & between A and int and between int and A. I don't want that because adding the compatibility with another type would require to re-implement many combinations of all operators which need to be supported.
Forcing implicit conversion from built-in types to A, so only operator & between A and A is required.
For flexibility and maintainability, solution 2 is much better I think. So I can implement the following class A instead:
class A {
public:
int x;
A(int i) : x(i) {}
A(unsigned int i) : x(i) {}
explicit operator int() {
return this->x;
}
explicit operator unsigned int() {
return static_cast<unsigned int>(this->x);
}
};
A operator &(const A& src1, const A& src2) {
return A(src1.x & src2.x);
}
Now, though conversions from/to int and unsigned int are both defined, I can perform whether (A and A), (A and int), (int and A) and (int and int).
However I can't compile the code:
b2 = a & b;
b3 = b & a;
Because as b2 and b3 are int and (a & b) (resp. (b & a)) return a A and cast from A to int must now be explicit, I have to write:
b2 = static_cast<int>(a & b);
b3 = static_cast<int>(b & a);
My question (finally) is:
Is there a way to code class A so I can do:
b2 = a & b;
b3 = b & a;
while keeping only one definition of operator &, between (A and A)? In theory, that could be done overloading operator =(const A&) of class int, which is technically impossible.
I think bipll means using free-standing operator& functions:
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x;
public:
explicit A(int i) : x{i}
{ }
explicit A(unsigned i) : x{static_cast<int>(i)}
{ }
operator int() const
{
return this->x;
}
operator unsigned() const
{
return static_cast<unsigned>(this->x);
}
};
A operator&(A const& lhs, A const& rhs)
{
return A(lhs.operator int() & rhs.operator int());
}
A operator&(A const& lhs, int rhs)
{
return A(lhs.operator int() & rhs);
}
A operator&(int lhs, A const& rhs)
{
return A(lhs & rhs.operator int());
}
A operator&(A const& lhs, unsigned rhs)
{
return A(lhs.operator unsigned() & rhs);
}
A operator&(unsigned lhs, A const& rhs)
{
return A(lhs & rhs.operator unsigned());
}
int main()
{
auto b = 2;
auto b2 = 0;
auto b3 = 0;
auto u = 2;
auto u4 = 0u;
auto u5 = 0u;
auto a = A{3};
b2 = a & b;
b3 = b & a;
u4 = a & u;
u5 = u & a;
cout << b2 << endl;
cout << b3 << endl;
cout << u4 << endl;
cout << u5 << endl;
}
I think I have just come across a solution. Please consider the following code:
class A {
public:
int x;
explicit A(int i) :
x(i) {
}
explicit A(unsigned int i) :
x(i) {
}
operator int() {
return this->x;
}
operator unsigned int() {
return static_cast<unsigned int>(this->x);
}
};
template<typename T> A operator &(const A& src1, const T& src2) {
return A(src1.x & src2);
}
template<typename T> A operator &(const T& src1, const A& src2) {
return A(src1 & src2.x);
}
int main() {
int b = 2, b2 = 0, b3 = 0;
A a(3);
b2 = a & b;
b3 = b & a;
std::cout << b2 << std::endl;
std::cout << b3 << std::endl;
return 0;
}
It just happens to work. The only problem I see (which is quite important though) is that you can't control the effects of operator & with built-in types you have not considered.
New question then:
Is there a way to restrict my template operator & to a given list of types (without template specialization)?

Content of array being rewritten after return

First things first, I have the below class A which at the same time have a nested class B:
// A.h
class A {
public:
class B;
A();
A(const A& a); // Copy constructor
B& operator[](const unsigned int& a) const;
A operator+(const A& a) const;
/*...*/
~A();
private:
/*...*/
unsigned int size;
B* b;
};
and I'm trying to use the overloaded + operator to "add" two A objects by adding the content of both b members of said objects, and assign the result to a third A object.
b is a dinamically allocated array of B objects.
B is a pretty basic class with just some unsigned int
here's the main function:
// main.cpp
int main(int argc, char** argv) {
A a1, a2, result;
a1.read(argv[1]); // Initialize b member with content read from a file
a2.read(argv[2]); // Initialize b member with content read from a file
result = a1 + a2; // Error [3]
getchar();
return 0;
}
The problem is that when trying to make the sum I get what I think are memory errors like: HEAP[main.exe]: Invalid address specified to RtlValidateHeap( 00A50000, 00A59938 )
here's the implementation of class A:
// A.cpp
A::A() : /*...*/, size(0), b(nullptr) {}
// Copy constructor
A::A(const A& a) : /*...*/, size(a.size), b(nullptr) {
b = new B[size]; // [1]
for (unsigned int i = 0; i < size; i++) {
(*this)[i] = a[i];
}
}
A::B& A::operator[](const unsigned int& i) const {
return b[i];
}
A A::operator+(const A& a) const {
if (size != a.size) {
exit(1); // Size must be the same on both operands
}
A tmp(*this); // Call to copy constructor
for (unsigned int i = 0; i < a.size; i++) {
tmp[i] += a[i];
}
return tmp; // Call to copy constructor [2]
}
A::~A() {
if (b != nullptr) {
delete[] b;
}
}
and of class B:
// B.h
class A::B {
public:
B();
B(unsigned char, unsigned char, unsigned char);
B& operator+=(const B& b);
private:
unsigned int a, b, c, d;
};
// B.cpp
A::B::B() : a(0), b(0), c(0), d(0) {}
A::B::B(unsigned char _a, unsigned char _b, unsigned char _c) {
/*...*/
}
A::B& A::B::operator+=(const B& b) {
/*...*/
return *this;
}
I'm using Visual Studio by the way, and when debugging I've observed:
b member of result points to the same address pointed by b in [1] when the copy constructor is called by the return statement in [2], so far so good
Until the return in [2] the content of b is all right, something like: 0x00669968 00 00 ff 00 00 ff 00 00 ..ÿ..ÿ..
After [3] the content of b in [1] and therefore the content of b member of result object becomes something like: 0x00669968 dd dd dd dd dd dd dd dd ÝÝÝÝÝÝÝÝ, I'm guessing is garbage
Note: all include directives and irrelevant sections of code have been ommited
I've been like two days shaking my head trying to figure out what's wrong with no luck so any help is greatly appreciated, thanks in advance.
I check your code and the problem is that you need a custom copy assignment for class A. In your main you have A a1, a2, result;, the default constructor is called for the 3 objects. Then, in the line result = a1 + a2;, the default copy assignment is called.
When you have pointers in your class and allocate the memory using new then you have to worry about copy constructor and copy assignment. Check this post and the rule of three.
I propose you the next code:
class A {
class B {
unsigned a, b, c, d;
public:
B() : a(0), b(0), c(0), d(0) { }
B(unsigned char a_, unsigned char b_, unsigned char c_) : a(a_), b(b_), c(c_), d(0) { }
// Copy constructor.
B& operator=(const B& b_) {
a = b_.a;
b = b_.b;
c = b_.c;
d = b_.d;
return *this;
}
B& operator+=(const B& b_) {
a += b_.a;
b += b_.b;
c += b_.c;
d += b_.d;
return *this;
}
};
unsigned size;
B* b;
public:
A() : size(0) { }
// Copy constructor.
A(const A& a) : size(a.size) {
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
}
// Copy assigment
A& operator=(const A& a) {
clear();
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
return *this;
}
B& operator[](unsigned pos) const {
if (pos > size) {
throw std::out_of_range("Out of range");
}
return b[pos];
}
A operator+(const A& a) const {
A tmp = *this;
if (size != a.size) {
throw std::out_of_range("Diferent sizes");
}
for (unsigned i = 0; i < a.size; ++i) {
tmp[i] += a[i];
}
return tmp;
}
void read(const char* file) {
clear();
size = size_;
b = new B[size];
/*
* Read your file and update b.
*/
}
void clear() {
if (size) {
delete[] b;
size = 0;
}
}
~A() {
clear();
}
};

Operator +/- overloading as a non member function in 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.