operator precedence question between `<<` and `==` - c++

#include <bits/stdc++.h>
using namespace std;
class point
{
public:
int x, y;
point(int a, int b)
{
x = a, y = b;
}
bool operator==(point &a)
{
if (a.x == x && a.y == y)
{
return 1;
}
else
{
return 0;
}
}
};
int main()
{
point a(5, 7), b(5, 7);
int t = a == b;
cout<<t; //it is working properly
cout<< (a==b); // it also
cout << a==b; //but it gives me compilation error
}
what is the reason...??
is there any fact of operator precedence...??
I don't know why it is giving compilation error...
as it is seen it looks fine

The << operator has higher precedence than the == operator. So this:
cout << a==b;
Is parsed as this:
(cout << a ) == b;
This causes an error because there is no overload of operator<< for cout that takes point as an argument.
The explicit parenthesis in your first example is the proper way to handle this.

Related

addition and subtraction of two numbers using operator overloading

#include<iostream>
using namespace std;
class add
{
private: int a,b;
public: add(int x=0)
{
a=x;
}
add operator+(add const &c) // sub operator-(sub const &c)
{ //{
add sum; // sub diff;
sum.a=a+c.a; // diff.a=a-c.a;
return sum; // return diff
} //}
void print()
{
cout<<"sum: "<<a;
}
};
int main()
{
add a1(10),a2(5); //sub s1(10),s2(5);
add a3=a1+a2; // sub s3=s1-s2;
a3.print(); // s3.print();
return 0;
}
Here I've written seperately but what to do if I need to do both in a single code?
I want a C++ code to perform them simultaneously
You can define any reasonable combination of:
Foo operator+(arg);
Foo operator-(arg);
Foo operator*(arg);
Foo operator/(arg);
And the arg can be another Foo or some other type entirely. For instance:
#include <iostream>
using namespace std;
class Operators {
public:
Operators() = default;
Operators(int v) : value(v) {}
Operators operator+(const Operators &other) {
return Operators{value + other.value};
}
Operators operator+(const int byValue) {
return Operators{value + byValue};
}
Operators operator-(const Operators &other) {
return Operators{value - other.value};
}
Operators operator-(const int byValue) {
return Operators{value - byValue};
}
Operators operator*(const Operators &other) {
return Operators{value * other.value};
}
Operators operator/(const Operators &other) {
return Operators{value / other.value};
}
int value = 0;
};
int main(int, char **) {
Operators first{10};
Operators second{20};
Operators result1 = first + second;
Operators result2 = first * second;
Operators result3 = first * 3;
Operators result4 = second / 2;
cout << "first + second == " << result1.value << endl;
cout << "first * second == " << result2.value << endl;
cout << "first * 3 == " << result3.value << endl;
cout << "first / 2 == " << result4.value << endl;
}
first + second == 30
first * second == 200
first * 3 == 30
first / 2 == 10
You'll see I overwrote operators that take two Operators objects, but I also wrote a few that take an integer argument, too.
I compiled and ran that with:
g++ --std=c++17 Whatever.cpp -o Whatever && Whatever

I can't seem to get the msvc linker to work properly on vscode

I have this really simple program that's made up of 2 files.
main.cpp has the main function:
[main.cpp]
#include <iostream>
#include <string>
#include "calculator.h"
using namespace std;
int main() {
Calculator calc;
do {
string op, left, right;
float out;
cout << endl << "insert an operator and two numbers: ";
cin >> op;
if (calc.isOperator(op)) {
cin >> left;
cin >> right;
out = calc.doOp(op, left, right);
cout << endl << "result: " << endl;
}
else
cout << endl << "invalid operator" << endl;
} while(true);
}
calculator.cpp has the Calculator class and calculator.h has a declaration for the class and every function or variable in it.
[calculator.cpp]
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
class Calculator {
vector<float>* mem_stack;
public:
Calculator() {
mem_stack = new vector<float>();
}
~Calculator() {
delete mem_stack;
}
float memPeek() {
return (*mem_stack).back();
}
float memPeek(const int& age) {
return (*mem_stack)[(*mem_stack).size() - age];
}
float doOp(const string& op, string& left, string& right) {
float a, b;
if (left[0] == 'r') {
left = left.substr(1, left.size() - 1);
a = memPeek(stoi(left));
}
else
a = stoi(left);
if (right[0] == 'r') {
right = right.substr(1, right.size() - 1);
b = memPeek(stoi(right));
}
else
b = stoi(right);
float out;
if (op == "+")
out = a + b;
else if (op == "-")
out = a - b;
else if (op == "*")
out = a * b;
else if (op == "/")
out = a / b;
(*mem_stack).push_back(out);
return memPeek();
}
bool isOperator(const string& op) {
bool out;
out = op == "+" && op == "-" && op == "*" && op == "/";
return out;
}
};
[calculator.h]
#pragma once
#include <vector>
#include <string>
class Calculator {
private:
std::vector<float>* mem_stack;
public:
Calculator();
~Calculator();
float memPeek();
float memPeek(const int& age);
float doOp(const std::string& op, std::string& left, std::string& right);
bool isOperator(const std::string& op);
};
When I try to compile the program I get unresolved linking errors in the main function. They all look like this:
main.obj : error LNK2019: unresolved external symbol
I get them for every function from calculator.cpp called in main, including the constructor and destructor
I have looked up everything I could find on this but I still get those errors. Could anybody help me?
I'm still just a rookie.
Welcome to StackOverflow!
You may have solved this in the meantime, but your problem is pretty simple: in your Calculator.cpp file, you're basically redeclaring another Calculator class, which shadows the original one, that ends up with no functions defined for it (just the declarations in the .h file). To solve this, you instead declare your member functions with ClassName::functionName() in the .cpp instead.
Didn't try compiling, but this should work:
[calculator.cpp]
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
Calculator::Calculator() {
mem_stack = new vector<float>();
}
Calculator::~Calculator() {
delete mem_stack;
}
float Calculator::memPeek() {
return (*mem_stack).back();
}
float Calculator::memPeek(const int& age) {
return (*mem_stack)[(*mem_stack).size() - age];
}
float Calculator::doOp(const string& op, string& left, string& right) {
float a, b;
if (left[0] == 'r') {
left = left.substr(1, left.size() - 1);
a = memPeek(stoi(left));
}
else
a = stoi(left);
if (right[0] == 'r') {
right = right.substr(1, right.size() - 1);
b = memPeek(stoi(right));
}
else
b = stoi(right);
float out;
if (op == "+")
out = a + b;
else if (op == "-")
out = a - b;
else if (op == "*")
out = a * b;
else if (op == "/")
out = a / b;
(*mem_stack).push_back(out);
return memPeek();
}
bool Calculator::isOperator(const string& op) {
bool out;
out = op == "+" && op == "-" && op == "*" && op == "/";
return out;
}
As a side note, I don't know of your programming background, but one thing struck me out as very odd in your code. Maybe you've come from Java or C#, where you always have to initialize object member variables; C++ is a bit more like C in this respect, in that it allows you to hold objects by value, and not only reference. Which means you don't have to have a pointer to your vector<float>, nor allocate/deallocate it yourself; let the compiler do the work for you and use it by value.
So, instead of doing std::vector<float>* mem_stack;, simply do std::vector<float> mem_stack;; this makes operations like (*mem_stack).push_back(out); (or the alternative mem_stack->push_back(out);, using the -> deference operator) much cleaner: mem_stack.push_back(out);

Operator overloading explanation

I am trying to understand an output of a short program where operator overloading is used.
The output is 137, where the (2+v).print() outputs 13 and 7 is from v.print();
#include <iostream>
using namespace std;
class V
{
int x;
public:
V(int a = 7, int b = 3) { x = a + b; }
void print() { cout << x; }
V operator+(int n)
{
return x++ + ++n;
}
};
V operator+(int lop, V rop)
{
return rop + lop;
}
int main()
{
V v(1, 6);
(2 + v).print();
v.print();
return 0;
}
I understand the basic concept of the operator overloading and I get that V rop is just a copy of the V v(1,6), and it doesn't change the output of v.print(); where x stays 7, but I don't get why it outputs 13, I always get to 10.
The problem is when trying to return an object of type 'V' from this operator:
V operator+(int n)
{
return x++ + ++n;
}
What you're trying to return here in an 'int' so it should be cast to an object of type 'V', the way it's done (casting from a primitive type to custom class) is using constructors. The only constructor you're having is with 2 optional parameters which creates the problem that it tries to make an object of one parameter only, so it's sent as a = 10, b = 3 (default value) and then the output is 13.
I recommend using multiple constructors to solve the problem if you don't want to change the members of the class.
class V
{
int x;
public:
V() { x = 10; }
V(int a) { x = a; }
V(int a, int b) { x = a + b; }
void print() { cout << x; }
V operator+(int n)
{
return x++ + ++n;
}
};
By this way you can call a default constructor which sets x to 10 as you previously did, another constructor with 1 parameter to cast from 'int' to 'V', and your normal constructor that takes a and b.
In your code when arrive at return (x++ + ++n); compiler create an object V so your constructor will be call again. then these assignment will be occurred a=10 and b=3. So you gotta save a and b values in another members.
Try this :
#include <iostream>
using namespace std;
class V {
int x;
int a;
int b;
public:
V(int a=7, int b=3) { x = a + b; this->a = a; this->b = b; }
void print() { cout << x - this->b; }
V operator+(int n) {
return (x++ + ++n);
}
};
V operator+(int lop, V rop) {
return rop + lop;
}
int main()
{
V v(1,6);
(2 + v).print();
v.print();
return 0;
}
Your (2 + v).print(); output will be 10.

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.

Order: An Analysis on Point Sorting

So I've made for myself a point printing class, that is supposed to have the user enter in 2-tuples; that is, x and y, that then prints them back to the user in ^order,^ where order means p1=(x,y)
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
class Point2D {
public:
Point2D();
Point2D(double a, double b);
double getx();
double gety();
void setx(double a);
void sety(double b);
virtual void print();
virtual void print(int a);
double angle();
private:
double x;
double y;
};
bool operator<( Point2D a , Point2D b );
int main() {
double my_x=-999;
double my_y=-999;
string my_color;
double my_weight;
vector<Point2D*> points;
cout << "Welcome to Point Printer! Please insert the x-and y-coordinates for your points and I will print them in sorted order! Just one rule, the point (0,0) is reserved as the terminating point, so when you are done enter (0,0).\n";
while(true)
{
cout << "x = ";
cin>>my_x;
cout << "y = ";
cin>>my_y;
if((my_x == 0)&&(my_y==0))
{
break;
}
points.push_back(new Point2D(my_x, my_y));
}
sort(points.begin(), points.end());
cout << "\n\n";
cout << "Your points are\n\n";
for(int i=0;i<points.size();i++)
{
cout<<i+1<<": ";
(*points[i]).print(); cout<<endl; // this is the printing gadget
}
for(int i=0; i<points.size(); i++)
{
delete points[i];
}
cout << endl << endl;
return 0;
}
double Point2D::angle()
{
double Angle = atan2(y,x);
if(Angle < 0)
{
return Angle + 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
}
return Angle;
}
bool operator< (Point2D a, Point2D b)
{
if (a.getx()*a.getx()+a.gety()*a.gety() < b.getx()*b.getx()+b.gety()*b.gety())
{
return true;
}
else if (a.getx()*a.getx()+a.gety()*a.gety() > b.getx()*b.getx()+b.gety()*b.gety())
{
return false;
}
if (a.getx()*a.getx()+a.gety()*a.gety() ==b.getx()*b.getx()+b.gety()*b.gety())
{
if (a.angle() < b.angle())
{
return true;
}
else if (a.angle() > b.angle())
{
return false;
}
}
return true;
}
Point2D::Point2D() { x = 0; y = 0; return;}
Point2D::Point2D(double a, double b) { x = a; y = b; return;}
double Point2D::getx() { return x;}
double Point2D::gety() { return y;}
void Point2D::setx(double a) { x = a; return; }
void Point2D::sety(double b) { y = b; return; }
void Point2D::print() {
cout<<"("<<x<<","<<y<<")";
return;
}
void Point2D::print(int a) {
print(); cout<<endl;
}
What I'm having trouble with is either one of the following:
sort
angle()
operator<(Point2D a, Point2D b)
Something different entirely...
In particular, the following points:
x = 1
y = 2
x = 2
y = 3
x = 1.1
y = 2.2
x = -10
y = 10
x = -5
y = -3
x = -5
y = 3
x = 5
y = -3
x = 5
y = 3
x = 0
y = 0
are not sorted in the correct order.
Any help would be much appreciated. Thank you.
The problem (or one of them) is the final statement in your comparison function.
return true;
Look at this block:
if (a.getx()*a.getx()+a.gety()*a.gety() ==b.getx()*b.getx()+b.gety()*b.gety())
{
if (a.angle() < b.angle())
{
return true;
}
else if (a.angle() > b.angle())
{
return false;
}
}
First of all, if we've gotten to this point, we've determined that the (x*x + y*y) calculations for both a and b are equal. Now let's assume that the angle is also equal. What happens? The first test fails because a.angle() is not less than b.angle(). Then the second test fails because a.angle() is not greater than b.angle(). Then you return true. In other words, you're saying that it is true that a is less than b, even though by all rights, they should be considered equal, and so you should return false. Instead of multiple tests on the angle, you can just return a.angle() < b.angle();, and that should do the trick. With some additional simplifications, your function should look something like this:
bool operator<(Point2d a, Point2d b)
{
double A = a.getx()*a.getx()+a.gety()*a.gety();
double B = b.getx()*b.getx()+b.gety()*b.gety();
if (A < B) return true;
if (A > B) return false;
return a.angle() < b.angle();
}
The problem is probably that you are storing and sorting pointers, not objects. The points will be compared not with your operator but their addresses. Try change points to vector<Point2d>
First of all just use (if your are just planning to sort 2D points) :
(Edit : See Benjamin Lindley comments below.)
bool operator < ( Point2D a, Point2D b)
{
return a.getx() < b.getx() ||
(a.getx()==b.getx() && a.gety()< b.gety() );
}
Another thing if use use std::cout in operator < ( Point2D a, Point2D b), you will notice it won't be called anytime.
The reason is this:
vector<Point2D*> points; // Vector of Point2D*
but bool operator< (Point2D a, Point2D b) is used for comparision.
Suggested Fixes:
vector<Point2D> points;
points.push_back(Point2D(my_x, my_y));
And accordingly, wherever applicable.
Also you can't define anything like
bool operator<(const Point2D* a, const Point2D* b)
Because of this:
C++03 standard, ยง13.5 [over.oper] p6:
An operator function shall either be a non-static member function or
be a non-member function and have at least one parameter whose type is
a class, a reference to a class, an enumeration, or a reference to an
enumeration.