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);
Related
I am wondering if I could write, for instance: <<(object, cout); or <<(cout,object); where object is a user defined class which has the << operator overloaded, just as one could write:
int a = +(2,3); and obtain the expected result, as in int a = 2 + 3;.
Furthermore, what should one do if this is possible, but requires a few steps? Should one overload the << operator with two different signatures?
just as one could write: int a = +(2,3); and obtain the expected
result, as in int a = 2 + 3;
No, you have a misunderstanding. +(2, 3) will go by the associativity of the comma operator and assign +3 (3) to the variable a.
Therefore, int a = +(2, 3) is the same as int a = 3, and not int a = 2 + 3
I am wondering if I could write, for instance: <<(object, cout); or
<<(cout,object);
No, you can't.
If you want to use the operators in that fashion then you should call its fully qualified name, for example:
operator+ instead of +
operator<< instead of <<
Note:
This will not work for fundamental datatypes. Take care of the class scope and namespaces when you are using the overloaded versions of these operators.
You can do this, e.g.
operator<<(std::cout, "hi");
This expression
int a = +(2, 3);
is not doing operator+. It's first applying the , sequence operator, which gives 3, and then applying unary +, which gives 3.
You can't do this
int a = operator+(2, 3); // error
because ints are fundamental types.
If you have user defined types S, then the following snippets have the same meaning
S s{};
std::cout << s;
auto x = s + s;
is the same as
S s{};
operator<<(std::cout, s);
auto x = operator+(s, s);
assuming the operators are defined for S, the correct operator will be called.
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.
I'm making a function that inputs a string class number and translates it into integers.
for example. I punch in 123 I'll get back 123 as an integer, or I punch in 1D2F I...guess I get it back? But I figured I'll turn any base number back to decimal. (But how would I make this string into a decimal if I'm not completely sure you can do math effectively with strings?
So far for my stringToInt function I have.
int StringToInt (string inputString){
int i;
int newIntegerLine;
for (i=0; i<inputString.length();i++){
//subtracts the ascii number of 0 from
//whatever character you input
newIntegerLine= (inputString.at(i)- '0');
}
return newIntegerLine;
}
I figured I can use the ascii numbers to get characters to integers. But when I run it whatever I put it is returned as 0. And I really am not sure how to approach the base number problem (What to do with A-F, perhaps if statements? Is there a more elegant way of doing this?). Can I call my base function within my StringToInt function? Or is there already a function I can use to accomplish this? Am I just complicating matters?
my base function (Which seems to work I guess? There seems to be a slight issue with binary numbers when I punch in 100 and say its in base 2 I get 24 back as it's decimal equivalent. Otherwise it works perfectly.)
int baseToDecimal (int numInput, int base){
int i, modSum;
modSum=numInput%10;
for(i=base;(numInput/=10)!=0;i*=base)
modSum+=numInput*i;
return modSum;
}
The old C way (atoi):
std::string foo = "1337";
int bar = atoi(foo.c_str());
Using std::istringstream:
std::string foo = "1337";
int bar;
std::istringstream(foo) >> bar;
C++11's std::stoi:
std::string foo = "1337";
int bar = std::stoi(foo);
which under the hood uses std::strtol:
std::string foo = "1337";
int bar = std::strtol(foo.str(), nullptr, 10);
And to add an example for #polkadotcadaver's mention of boost::lexical_cast:
std::string foo = "1337";
int bar = boost::lexical_cast<int>(foo);
Don't forget to add appropriate error handling!
I am fairly new to C++ and I have been reading and writing some of my own code. I see these operators from time to time, if that is even the right word to use?
+= // Not sure what it means
So my question is: what do they mean/do, and what are they called?
For further reference, I'd like to know what they are called so I can easily look it up (searching simply for "+=" for instance yielded nothing).
Edit: For anyone else who does not know the meaning (or in my case knew the name of these) I found this Wikipedia link which might come of handy to other people: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
Yes, these are operators. More specifically, they are known as compound assignment operators. Here's the full list of them:
*= /= %= += -= >>= <<= &= ^= |=
They are defined like so:
The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
So x += 5; is almost the same as x = x + 5;.
You can think of it as a modifying addition. If you just do x + 5, the result of the expression is what you get if you add x and 5 together, but x hasn't changed. If you do x += 5;, x actually has 5 added to its value.
its just an abbreviation:
a+=2; means a=a+2;
of course as many operators: you can overload it to give it alternative meaning, ans actually we do it often to provide meaning for example in the case what it means to add int to our class SomeClass:
SomeClass s;
s+=1; //operator+=(SomeClass& s, int i){} is used here
class A{
public:
A():i_(123){}
~A(){}
int i(){return i_;}
A const& operator+=(int i){
std::cout<<"operator+=";
this->i_=i_+i;
}
private:
int i_;
};
int main(int argc, char** argv) {
A a1;
a1+=3;
std::cout<<a1.i();
return OK;
}
output: operator+=126
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.