how to overloading without arithematic operator - c++

#include <iostream>
using namespace std;
class Expression
{
private :
double val;
public :
Expression() : val(0)
{
}
Expression(double v) : val(v)
{
}
Expression operator +(Expression a)
{
Expression a1;
a1.val = val + a.val;
return a1;
}
Expression operator --()
{
Expression temp1;
temp1.val = --val;
return temp1;
}
Expression operator --(int)
{
return Expression(val--);
}
Expression operator * (Expression b1)
{
Expression b;
b.val = val * b1.val;
return b;
}
double showvalue()
{
return val;
}
};
int main()
{
Expression E1;
Expression E2(5.5) , E3;
E3(2.0);
cout << E3.showvalue();
cout << endl;
Expression E4;
E4 = E3;
E1 = E2+--E3*E4--;
cout << E1.showvalue();
return 0;
}
In the main where I have E3(2.0)
How would I overload so it would work without doing, Expression E3(2.0);
just E3(2.0);
Our teacher says there is a way to do this, so I want to know it
Again
I want it to be only E3(2.0) or any value inside, so it works
(filling so I can post
don't read this just adding details for no reason beacasue it says so)

You might have operator() acting as assigment.
class Expression
{
public:
Expression& operator=(double d) { val = d; return *this; }
void operator()(double d) { *this = d; }
// ...
};

Related

std::any object cast to reference type, change its value, but original object is not changed

I was trying to see if std::any object can cast to reference type, and see whether changing the casted reference means to change original object. As below:
struct My {
int m_i;
My() : m_i(1) {}
My(const My& _) : m_i(2) {}
My(My&& m) : m_i(3) {};
My& operator = (const My& _) { m_i = 4; return *this; }
My& operator = (My&& _) { m_i = 5; return *this; }
};
int main() {
any a = My();
My& b2 = any_cast<My&>(a);
b2.m_i = 6;
cout << any_cast<My>(a).m_i << endl;
return 0;
}
It prints 2. For my I expected that, as long as b2 is a reference, I hope changing b2.m_i will effect a.m_i, right? But result seems not as my expectation.
Where did I get wrong, is my expectation valid?
Thanks!
Look at your example without any any:
#include <any>
#include <iostream>
using std::cout;
using std::endl;
using std::any;
using std::any_cast;
struct My {
int m_i;
My() : m_i(1) {}
My(const My& _) : m_i(2) {}
My(My&& m) : m_i(3) {};
My& operator = (const My& _) { m_i = 4; return *this; }
My& operator = (My&& _) { m_i = 5; return *this; }
};
int main() {
My a = My();
My& b2 = a;
b2.m_i = 6;
cout << static_cast<My>(a).m_i << endl;
}
Output is:
2
Because static_cast<My>(a) is creating a temporary copy of a and your copy assigns 2 to the member. You can use static_cast<My&>(a) to not make a copy.
After removing your somewhat weird copy and assignment, you can also get the same result with any:
struct My {
int m_i = 1;
};
int main() {
any a = My();
My& b2 = any_cast<My&>(a);
b2.m_i = 6;
cout << any_cast<My>(a).m_i << endl; // copy
cout << any_cast<My&>(a).m_i << endl; // no copy
}
Output:
6
6

Is it possible to overload an operator taking references/pointers to an abstract class as input?

I am working on a c++ programme that has to carry out differentiation by symbol of a given expression. For example, the derivative of (5x) will be ((0*x) + (5*1)) . Note that the integer coefficient is also treated as a variable or function hence, the product rule is used. Another example: (5 + (8 * x)) will evaluate to (0 + ((0*x) + (8*1))) . No further simplication is required.
The task requires that there be an abstract base class "Expression" with pure virtual methods and from it must stem derived classes such as Number, Variable etc. The goal is to read expressions of the form given above and print out their respective symbol-derivatives.
I have had some success in tackling this task without overloading any operators. Here is what I mean:
#include <iostream>
#include <string>
class Expression
{
public:
virtual Expression* diff() = 0; //Derivative Calculator
virtual void print() = 0;
virtual std::string stringget() = 0; //Prints current expression
};
//--------------------Number Class--------------------//
class Number : public Expression
{
private:
int num;
std::string snum;
public:
//Constuctors
Number(int n) : num(n), snum(std::to_string(num)) { }
Number() : num(0), snum("0") { }
// Rule of three does not apply as class does not contain pointer variables
//Differentiation function
Expression* diff()
{
num = 0;
snum = std::to_string(0);
return this;
}
void print()
{
std::cout << num << std::endl;
}
std::string stringget()
{
return snum;
}
};
//--------------------Variable Class--------------------//
class Variable : public Expression
{
private:
std::string var;
public:
//Constructors
Variable(std::string v) : var(v) { }
Variable() : var("x") { }
//Functions
Expression* diff() override
{
var = "1";
return this;
}
void print() override
{
std::cout << var << std::endl;
}
std::string stringget() override
{
return var;
}
};
//--------------------Addition/Sum Class--------------------//
class Add : public Expression
{
private:
std::string sum;
std::string plus = "+";
std::string leftpar = "(";
std::string rightpar = ")";
Expression* laddend; //left addend storage
Expression* raddend; //right addend storage
public:
//Constructors
Add(Expression* a, Expression* b)
{
sum = leftpar + (*a).stringget() + plus + (*b).stringget() + rightpar;
laddend = a;
raddend = b;
}
Add(Expression& a, Expression& b)
{
sum = leftpar + (a).stringget() + plus + (b).stringget() + rightpar;
laddend = &a;
raddend = &b;
}
//Copy Constructor
Add(const Add& src) : sum(src.sum), plus(src.plus), leftpar(src.leftpar), rightpar(src.rightpar), laddend(src.laddend), raddend(src.raddend) { }
//Assignment operator
Add& operator =( Add& src ) { sum = src.sum; return *this; }
//Destructor
~Add() { delete laddend; delete raddend; laddend = NULL; raddend = NULL;}
//
void print() override
{
std::cout << sum << std::endl;
}
//derivative calculator
Expression* diff() override
{
laddend = (*laddend).diff();
raddend = (*raddend).diff();
sum = leftpar + (*laddend).stringget() + plus + (*raddend).stringget() + rightpar;
return this;
}
//Expression getter
std::string stringget() override
{
return sum;
}
//Overload
Expression& operator +( Expression* rhs)
{
Add* res = new Add(this, rhs);
return *res;
}
};
//--------------------Product/Multiplication Class--------------------//
class Mul : public Expression
{
private:
std::string product = "(";
std::string ast = "*";
std::string plus = "+";
std::string leftpar = "(";
std::string rightpar = ")";
Expression* multiplicand; //left argument storage
Expression* multiplier; //right argument storage
public:
//Constructors
Mul(Expression* a, Expression* b)
{
product = product + (*a).stringget() + ast + (*b).stringget() + rightpar;
multiplicand = a;
multiplier = b;
}
void print() override
{
std::cout << product << std::endl;
}
Expression* diff() override
{
std::string lvar = (*multiplicand).stringget(); //before differentiation
std::string rvar = (*multiplier).stringget(); //before differentiation
multiplicand = (*multiplicand).diff();
multiplier = (*multiplier).diff();
product = leftpar + leftpar + (*multiplicand).stringget() + ast + rvar + rightpar + plus + leftpar + lvar + ast + (*multiplier).stringget() + rightpar + rightpar;
return this;
}
std::string stringget() override
{
return product;
}
//Overload
Expression& operator *( Expression* rhs)
{
Mul* res = new Mul(this, rhs);
return *res;
}
};
int main()
{
Expression* test = new Mul(new Number(6), new Variable("x"));
std::cout << "Current Expression: " << test->stringget() << std::endl;
Expression* test2 = test->diff();
std::cout << "Differentiated Expression: " << test2->stringget() << std::endl;
Add x(test, test2);
// x = test + test2 * test;
delete test;
return 0;
}
Which successfully compiles with the following output:
Current Expression: (6*x)
Differentiated Expression: ((0*x)+(6*1))
Now, the expression (6*x) was created by means of the line
Expression* test = new Mul(new Number(6), new Variable("x"));
But since my goal is to read expressions of the form (6*x) and even more complex expressions e.g (((4*x)+(x*x))-x) and then interpret them and finally differentiate, the only way is to overload the operators. This is where I'm getting problems.
The Problems
As you have might have noticed in the code, I have overloaded the addition and multiplication operators. However, when I try to run code such as
x = test + test2 * test1;
(This line is commented out in the provided code above) I get an error. Moreover, even with just one operator, for instance,
test = test + test2;
I get the error
error: invalid operands of types 'Expression*' and 'Expression*' to binary 'operator+'|
or
error: invalid operands of types 'Expression*' and 'Expression*' to binary 'operator+'|
This doesn't make sense to me since the parameter types coincide.
What Else Have I tried?
I've tried to pass the parameters by reference, as well as by const reference but still the same result. I also tried to write the operator overload description as a non-member function but that gives the error
must have an argument of class or enumerated type
I have also tried changing the return types from Expression& to Expression* and making the necessary subsequent edits but the errors are the same. I've even tried to implement the rule of threes for all the classes - even though it is not necessary - but the result is the same.
I'd appreciate any help on where I am missing it.

Use of the chain method in the continuation of the copy constructor/initialization in one declaration statements in c++?

As you know, we usually use the return by reference for the method chaining, I use the return by reference in the first code and the output is as I have predicted. In the second code block, when I did not use the return by reference, the chain was broken and my expected output was not generated, but in the third code block, I have reached the desired result using the chain method in continuation of the copy constructor / initialization in one declaration statements (without using return by reference), the question is, what is the logic behind the third code that protects the chain from breaking?
class Calc
{
private:
int m_value;
public:
Calc(int value = 0) : m_value{ value } {}
Calc& add(int value) { m_value += value; return *this; }
Calc& sub(int value) { m_value -= value; return *this; }
Calc& mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
int main()
{
Calc calc;
calc.add(5).sub(3).mult(4); // its OK and output 8
std::cout << calc.getValue() << '\n';
return 0;
}
class Calc
{
private:
int m_value;
public:
Calc(int value = 0) : m_value{ value } {}
Calc add(int value) { m_value += value; return *this; }
Calc sub(int value) { m_value -= value; return *this; }
Calc mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
int main()
{
Calc calc;
calc.add(5).sub(3).mult(4); // its NOT OK and output 5
std::cout << calc.getValue() << '\n';
return 0;
}
class Calc
{
private:
int m_value;
public:
Calc(int value = 0) : m_value{ value } {}
Calc add(int value) { m_value += value; return *this; }
Calc sub(int value) { m_value -= value; return *this; }
Calc mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
int main()
{
Calc calc = Calc{0} // copy constructor / initialization
.add(5) // method chaining
.sub(3) // method chaining
.mult(4); // method chaining, its OK and output 8
std::cout << calc.getValue() << '\n';
return 0;
}
what is the logic behind the third code that protects the chain from breaking?
Chain does get break, but you use the final result to assign to calc
Calc calc = Calc{0}.add(5).sub(3).mult(4);
is equivalent to
Calc calc = Calc{2}.mult(4);
What ultimately gets copy constructed into calc is a temporary Calc object when multiplied by 4.

c++ Copy constructors and destructors

I am learning constructors and Destructors in c++; Help me grasp my mistakes even if they are silly...
HERE is a code I have written to perform addition using classes in c++; This creates two summands of datatype num and employs the constructor sum() to perform sum of the two numbers; However when everything was goin' alright, I stumbled upon creating a copy constructor for num , (Although not necessary but still for practice)... without the dynamic object of the class sum it is not possible to run the code anyway(without removing the copy constructor)... Help me improve my code and my mistakes in the code below; Also I wanna know how to make use of the copy constructor in this program; the problem being that in the destructor the delete operation is being performed multiple times on the same piece of memory (I suppose)
Here's my Code
#include<iostream>
#include<new>
using namespace std;
class num
{
public:
int *a;
num(int x)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1";
exit(1);
}
*a=x;
}
num(){ }
num(const num &ob)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1''";
exit(2);
}
*a=*(ob.a);
}
~num()
{
cout<<"Destruct!!!";
delete a;
}
};
class sum:public num
{
public:
int add;
sum(num n1,num n2)
{
add=*(n1.a)+*(n2.a);
}
int getsum()
{
return add;
}
};
int main()
{
num x=58;
num y=82;
sum *s=new sum(x,y);
cout<<s->getsum();
delete s;
return 0;
}
I may miss something - didn't use new/delete for too long, but tried to correct all what I noticed.
P.S. always use smart pointers.
#include <iostream>
#include <exception>
#include <new>
using namespace std;
int* allocate(const char* err_msg, int exit_code)
{
int* a = nullptr;
try
{
a = new int;
}
catch (bad_alloc&)
{
cout << err_msg << endl;
exit(exit_code);
}
return a;
}
class num
{
int* a = nullptr; // always should be initialized here
public:
num() noexcept : a(nullptr) // or here
{}
/*explicit*/ num(int x) : a(allocate("1", 1))
{
*a = x;
}
num(const num& ob) : a(allocate("1''", 2))
{
*a = *(ob.a);
}
// rule of zero/three/five
// default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
num& operator =(const num& ob)
{
if (&ob == this)
{
return *this;
}
*a = *(ob.a);
return *this;
}
~num()
{
cout << "Destruct!!!";
delete a;
a = nullptr; // usefull for debug
}
int value() const
{
if (a == nullptr)
{
throw runtime_error("a == nullptr");
}
return *a;
}
};
class sum
{
int add = 0;
public:
sum(const num& n1, const num& n2)
{
add = n1.value() + n2.value();
}
int getsum() const
{
return add;
}
};
int main()
{
const num x = 58;
const num y = 82;
const sum* s = new sum(x, y);
cout << s->getsum() << endl;
delete s;
return 0;
}

reassign value not work in operator = overloading

The MWE is
#include <iostream>
using namespace std;
class N {
public:
float x;
N() { x = 0.0; }
N(float a) { x = a; }
//N(N &n) { x = n.x; }
N &operator=(float f) { cout << "########";return *new N(f); }
};
int main() {
N a;
a = 3.0;
cout << a.x;
return 0;
}
What I expect is: it prints 3, but it actually prints 0. It seems the value didn't change.
Then I change it into
x = f; return *this;
It worked, why?
Of course it doesn't change. You don't change it in your assignment operator. Instead you return a pointer to a new value allocated on the heap...and ignore that result.