So I'm supposed to write a program that has num and denom as integer data members of the Fractions class. I'm also supposed to have member functions that can display an object's data values and an overloaded operator function for +. My program says my subscripted items are an invalid data type, but I don't know how to allow for the second fraction without them. Does anyone know how I can fix this?
My code is the following:
#include <iostream>
#include <cmath>
using namespace std;
int a, b, c;
class Fractions
{
private:
int num;
int denom;
public:
Fractions(int=1, int=1);
void operator!(void) const;
Fractions operator+(const Fractions&) const;
};
Fractions::Fractions(int n, int d)
{
if( d != 0)
num= n;
denom= d;
}
Fractions Fractions::operator+(const Fractions& f) const
{
a= num/denom;
b= num[1]/denom[1];
c= a + b;
c= (num * denom[1]+ denom * num[1])/(denom * denom[1]);
return c;
}
int main()
{
return 0;
}
You've declared num and denom as int but in your function you're treating them like arrays: b= num[1]/denom[1];
That won't work. What is it you want to do with this line b= num[1]/denom[1];? Is the idea to divide by the value of the fraction you're adding? If so maybe what you want is: b = f.num/f.denom;
My algebra isn't the best, but I can't recall using division when adding fractions, but that might be another question (or I might have it wrong).
The most immediate issue that is causing the error you're specifying is caused by trying to do:
b= num[1]/denom[1];
You initialized b, num and denom as an int, not an integer array. But you are trying to access an element of num and denom as if they were arrays.
Either initialize an array of integers for each or dropping the access operator for them will fix the error, but I don't believe it will give you your desired result.
The way you're overloading the '+' operator will not work. Since you have the '+' operator as a member, the object of that class becomes the left hand side of the operator, and what you are passing (const Fractions& f) becomes the right hand side.
You are not using the 'f" variable that you pass in at all, nor are you affecting that instance's members. All you are doing is changing some global variables that really aren't necessary. I recommend you read up on operator overloading since it seems you don't quite understand how it works.
Related
As a C++ learner, I came across the following piece of code from C++ Language Tutorial and got two questions, could any expert provide some guidance on those?
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int
(*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return (g);
}
int main () {
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
In function "operation" definition:
Question 1: for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?
Question 2: for "return(g)", I'm wondering why we put parenthesis for g?
And for "int (*minus)(int,int) = subtraction;" in the main function, is that okay if we write the following instead?
int (*minus)(int,int)
minus = subtraction
Question 1: for g = (*functocall)(x,y), does it deference the
pointer that points to a function (ex.subtraction) and assign it to g?
Answer: No.
(*functocall)(x,y);
is simply one allowable syntax for invoking the function from the pointer passed as a parameter. It is entirely equivalent to:
functocall(x,y);
Which simply eliminates the (*...) syntax which is allowable but unnecessary.
Question 2: for return(g), I'm wondering why we put parenthesis for
g?
The parenthesis too are discretionary and are superfluous to the return. Simply providing:
return g;
is all that is needed as there is no expression requiring evaluation priority provided by the enclosing (..).
Before I start, your code uses way more parenthesis than it needs.
Here is the same code, better formatted and reduced:
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return a+b; }
int subtraction (int a, int b)
{ return a-b; }
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = functocall(x,y);
return g;
}
int main () {
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n<<"\n";
return 0;
}
for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?
In a nutshell - yes. When calling a function through it's pointer, it is not necessary to explicitly dereference it. I know, it's surprising and counter to the way pointers are typically used.
Think of it this way. Whenever you are just writing the name of a function, you are essentially getting the function's pointer. This is why you wrote as you did, rather than write:
m = operation (7, 5, &addition);
You do not need to explicitly dereference when using a function pointer for the same reason you do not need to explicitly use the address of operator when taking its address in the first place.
Question 2: for "return(g)", I'm wondering why we put parenthesis for g?
There is positively no good reason to. In fact, there is no reason to do it for any of your return statements.
And for "int (*minus)(int,int) = subtraction;" in the main function,
is that okay if we write the following instead?
int (*minus)(int,int);
minus = subtraction;
Personally, I recommend you use:
int (*minus)(int,int) = nullptr;
minus = subtraction;
so as not to leave uninitialized variables, but otherwise, yes, absolutely. A pointer to function variable is just like any other variable.
I have code which has a lot of conversions from double to int . The code can be seen as
double n = 5.78;
int d = n; // double implicitly converted to a int
The implicit conversion from double to int is that of a truncation which means 5.78 will be saved as 5 . However it has been decided to change this behavior with custom rounding off .
One approach to such problem would be to have your own DOUBLE and INT data types and use conversion operators but alas my code is big and I am not allowed to do much changes . Another approach i thought of was to add 0.5 in each of the numbers but alas the code is big and i was changing too much .
What can be a simple approach to change double to int conversion behaviour which impact the whole code.
You can use uniform initialization syntax to forbid narrowing conversions:
double a;
int b{a}; // error
If you don't want that, you can use std::round function (or its sisters std::ceil/std::floor/std::trunc):
int b = std::round(a);
If you want minimal diff changes, here's what you can do. Please note, though, that this is a bad solution (if it can be named that), and much more likely leaving you crashing and burning due to undefined behavior than actually solving real problems.
Define your custom Int type that handles conversions the way you want it to:
class MyInt
{
//...
};
then evilly replace each occurence of int with MyInt with the help of preprocessor black magic:
#define int MyInt
Problems:
if you accidentally change definitions in the standard library - you're in the UB-land
if you change the return type of main - you're in the UB-land
if you change the definition of a function but not it's forward declarations - you're in the UB/linker error land. Or in the silently-calling-different-overload-land.
probably more.
Do something like this:
#include <iostream>
using namespace std;
int myConvert (double rhs)
{
int answer = (int)rhs; //do something fancier here to meet your needs
return answer;
}
int main()
{
double n = 5.78;
int d = myConvert(n);
cout << "d = " << d << endl;
return 0;
}
You can make myConvert as fancy as you want. Otherwise, you could define your own class for int (e.g. myInt class) and overload the = operator to do the right conversion.
Consider following code:
#include <iostream>
using namespace std;
int aaa(int a) {
cout << a * 0.3 << endl;
return a * 0.3;
}
int main()
{
cout << aaa(35000);
}
It prints out:
10500
10499
Why output differs?
I have a workaround to use "return a * 3 / 10;" but I don't like it.
Edit:
Found that doing "return float(a * 0.3);" gives expected value;
The result of 0.3*35000 is a floating point number, just slightly less than 10500. When printed it is rounded to 10500, but when coerced into an int the fractional digits are discarded, resulting in 10499.
int * double expression yields double, that's what the first thing prints.
Then you convert to int chopping the remaining part (even if it's almost there, sitting at 10500-DBL_EPSILON), and pass that back. The second prints that value.
float-int conversions should be made with care, better not at all.
a * 0.3 has type double. The call inside aaa calls
ostream& operator<< (double val);
whereas the one outside calls
ostream& operator<< (int val);
You'd get a warning (if you turn them on - I suggest you do) that the implicit cast from double to int isn't recommended.
I copied this program from a c++ practice book. What's going on behind the scenes?
The expected output is:
sum=30 sum=70
#include<iostream>
using namespace std;
class M
{
int x;
int y;
public:
void set_xy(int a, int b)
{
x=a;
y=b;
}
friend int sum(M m);
};
int sum (M m);
//so far so good, problem begins from here. what's happening after here?
{
int M ::*px = &M ::x;
int M ::*py = &M ::y;
M *pm =&m;
int s= m.*px+ pm->*py;
return s;
}
int main()
{
M n;
void (M :: *pf)(int, int) = &M ::set_xy;
(n.*pf)(10, 20);
cout <<"sum=" << sum(n) << endl;
M *op= &n;
(op-> *pf)(30,40);
cout << "sum=" << sum(n)<< endl;
cin.ignore();
getchar();
return 0;
}
The problem is because of extra whitespace at op-> *pf:
(op->*pf)(30,40); // ok
I think #fefe has probably said the reason in comment. ->* is a single operator, similar to .*. So, if those 2 are separated, then it will result in different syntax, which gives compiler error.
Take a look at Pointer to class data. And for the error, ->* is an operator, you can't put a space between them.
iammilind bet me to the error; op-> *pf must be changed so that you have ->* together as a single operator - a pointer to member operator (couldn't find a better link). The whitespace in op ->* pf is perfectly valid.
That's the same for something like i++; ++ is a single operator and will cause an error if you try and have i+ +.
Now for what it's doing. The example is of a pointer to a member function. pf is being declared as a member function of class M, that takes two int arguments with a void return type. It's being initialized to point to the M::set_xy function.
Inside main:
n is of type M, therefore in order to use pf to call set_xy of n you'd use the .* operator: (n.*pf)(10, 20);. That's equivalent to n.set_xy(10, 20);.
Since op is of type M* (a pointer to an M object), you'll need to use the ->* operator and call the function pointed to by pf as: (op->*pf)(30, 40);, which is equivalent to op->set_xy(30, 40);
Inside sum:
The examples are simply of pointers to member/instance variables, as opposed to member functions. It's simply demonstrating how you would add together m.x and m.y using those types of pointers.
I have an issue, i need to add two class members using a operator overload. issue also is that the members i need to add are strings.. i tried using stringstream but i didnt seem to work, an infinite loop of errors occur. is there a very easy way to turn a string into a integer to add? or at least a way to add two strings to print out the sum
class PlayingCard
{
public:
char suit;
string rank;
PlayingCard operator +();
};
PlayingCard deck[52];
PlayingCard player[10];
PlayingCard dealer[10];
int playerHits = 2;
int dealerHits = 2;
PlayingCard PlayingCard::operator+()
{
int r1;
int r2;
stringstream pr1;
stringstream pr2;
string temp1 = player[1].rank;
string temp2 = player[2].rank;
pr1 << temp1;
pr2 << temp2;
pr1 >> r1;
pr2 >> r2;
return(r1 + r2);
}
Your operator+ does not take any parameters and therefore cannot work.
A member operator+ has to have the following signature:
class X {
X operator+(const X &b);
};
A free operator+ needs to look that way:
X operator+(const X &a, const X &b);
Well, that is one way to go.
I suggest you get back to the books ;)
You might want to first define what you mean by the operation of "adding two playing cards together." Let's say I have the jack of spades and the queen of hearts, physically in my hand. As physical entities, those don't add.
Their rank, however does; we could say jack + queen => 11 + 12 => 23 if we assign integer values to their ranks. Obviously there is no "23 card". Therefore, adding two PlayingCards together can not reliably return a valid PlayingCard.
The question is, would it just be easier to query their rank when it is needed? For example:
if (card1.rank + card2.rank > 21) {
// dealer wins
}
In this case, there isn't even a for an intermediate PlayingCard to be returned -- all we care about is the sum of the ranks of card1 and card2.
Sorry, I've deviated from your source a bit...the above is assuming you would store the rank as an int, as you had in your previous question. This method is highly preferable since you will be doing mathematical operations on them (like my dumb example above).
How about just using atoi?
atoi(player[1].rank.c_str());
Here you define the return type as PlayingCard
PlayingCard PlayingCard::operator+()
But here you return an integer:
int r1;
int r2;
// STUFF
return(r1 + r2);