#include <iostream>
#include <stdint.h>
usingnamespace std;
typedef int64_t RAT_INT;
struct RAT{
RAT_INT Num, Den;
RAT(RAT_INT num = 0, RAT_INT den = 1){
Num = num;
Den = den;
}
template <class T>
T Real(){
return (T)Num/Den;
}
RAT_INT Gcd(){
RAT_INT num = Num, den = Den;
while(num){
RAT_INT tmp;
tmp = num;
num = den % num;
den = tmp;
}
return den;
}
RAT Red(){
RAT_INT div = Gcd();
return RAT(Num / div, Den / div);
}
RAT Reda(){
return *this = Red();
}
RAT Sq(){
return *this * *this;
}
RAT Sqa(){
return *this = Sq();
}
booloperator== (RAT rat){
return Num*rat.Den == rat.Num*Den;
}
booloperator!= (RAT rat){
return !(*this == rat);
}
booloperator> (RAT rat){
if((Den >= 0 && rat.Den >= 0) ||
(Den < 0 && rat.Den < 0)){
return Num*rat.Den > rat.Num*Den;
}else{
return Num*rat.Den < rat.Num*Den;
}
}
booloperator< (RAT rat){
return rat > *this;
}
booloperator>= (RAT rat){
return !(*this < rat);
}
booloperator<= (RAT rat){
return !(*this > rat);
}
/*
RAT operator= (RAT_INT i){
return *this = RAT(i);
}
*/
RAT operator- (){
return RAT(-Num, Den);
}
RAT Rec(){
return RAT(Den, Num);
}
RAT operator+ (RAT rat){
return RAT(Num*rat.Den + rat.Num*Den, Den*rat.Den).Red();
}
RAT operator- (RAT rat){
return *this + -rat;
}
RAT operator* (RAT rat){
return RAT(Num * rat.Num, Den * rat.Den).Red();
}
RAT operator/ (RAT rat){
return *this * rat.Rec();
}
RAT operator+= (RAT rat){
return *this = *this + rat;
}
RAT operator-= (RAT rat){
return *this = *this - rat;
}
RAT operator*= (RAT rat){
return *this = *this * rat;
}
RAT operator/= (RAT rat){
return *this = *this / rat;
}
};
std::ostream& operator<< (std::ostream& os, RAT rat){
return os << rat.Num << "/" << rat.Den;
}
int main(){
cout << 1 + 2 << endl;
cout << RAT(1) + 2 << endl;
// cout << 1 + RAT(2) << endl;
return 0;
}
3
3/1
Two questions:
1) In the second line in main, how does C++ know to convert 2 to the appropriate RAT?
2) Is it possible to make the third line in main valid without adding global operators for all the member operators to support plain integers?
Why's that? I thought the point of classes was to include member functions to remove the redundancy of functions with struct arguments.
No. That doesn't even play into the "point" of classes. Every class function has a "hidden" pointer argument which you may refer to inside the function as this.
The point of classes is to encapsulate data and the functions which manipulate it. When all of your data is public, there is no encapsulation (and no need for member functions.) Were the data not public, you would want to limit the number of member functions to as few as possible, so that those functions that needn't be member functions (or, in other words, could be implemented in terms of other member functions) don't have access to private data.
Would it make sense to have to add a new operator<< overload to the std::ostream class everytime we needed to overload it for a new class?
I use member functions simply for convenience; it's less typing. I think programming should take into consideration some aspect of convenience. I see no reason why it'd be more better to make the functions global, as these operations are directly involved with the RAT class. You talk about limiting the number of member functions, but I don't see why.
It wouldn't make sense to add a new operator+ overload to RAT when I wanted to overload it for a new class either, so in that case I'd define a global operator.