C++面向对象:实现Fraction类 | variadic templates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//Fraction.h
#pragma once
#include <iostream>
#include <string>
 
using namespace std;
 
int& __gcd(int&, int&);
 
class Fraction {
public:
    explicit Fraction(int num, int den = 1): m_numerator(num), m_denominator(den) {
        int t = __gcd(num, den); //这里不能传(m_numerator, m_denominator), 因为原函数是引用传参
        //约分
        m_numerator /= t;
        m_denominator /= t;
    }
 
    operator double() const { return (double)m_numerator / m_denominator; } //conversion function 转换函数
    double operator +(const double& d) const { return (double)m_numerator / m_denominator + d; }
    Fraction operator +(const Fraction&) const;
    operator string() const { return to_string(m_numerator) + '/' + to_string(m_denominator); } //转换函数
 
    bool operator < (const Fraction& f) {
        //a/c = ad/cd, b/d = bc/cd
        return m_numerator * f.m_denominator < m_denominator * f.m_numerator;
    }
 
private:
    int m_numerator;
    int m_denominator;
 
    friend int& __gcd(int&, int&);
};
 
Fraction Fraction::operator +(const Fraction& f) const {
    //a/c + b/d = (ad + bc) / cd
    int num = m_numerator * f.m_denominator + m_denominator * f.m_numerator;
    int den = m_denominator * f.m_denominator;
    return Fraction(num, den);
}
 
inline int& __gcd(int& a, int& b) {
    while (a % b != 0) {
        int t = a % b;
        a = b;
        b = t;
    }
    return b;
}
 
//模板泛化
template<class T>
inline const T& min(const T& a, const T& b) {
    return b < a ? b : a;
}
 
//模板特化
template<>
struct hash<Fraction> {
    double operator()(const Fraction& f) { return double(f); }
};
 
 
//variadic templates, 可变参数模板
void show() { cout << endl; } //传入firstArg和args...均为空时调用该函数
 
template<typename T, typename... Types>
void show(const T& firstArg, const Types&... args) {
    cout << firstArg << " " ;
    show(args...);
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//Fraction.cpp
#include "Fraction.h"
 
int main() {
     
    cout << __cplusplus << endl; //C++11
     
    //conversion function
    Fraction f0(3);
    Fraction f1(3, 2);
    Fraction f2(9, 6);
    show(f0, f1, f2);
    show(string(f0), string(f1), string(f2));
    show(f0 + f1, f1 + 2.7);
 
    Fraction f3(f0 + f2);
    Fraction f4 = f0 + f2;
    double f5 = f0 + 2.1;
    //Fraction f6 = f0 + 2.1; //non-explicit ctor时, 情况一: 2.1由double转换为Fraction, 情况二: f6由double转换为Fraction, 会引起ambiguous Err
    //Fraction f7 = f0 + 2.1; //explicit ctor时, double转化为Fraction的隐式转换被禁用, 本行报错
    show(f3, f4, f5);
    //show(f6, f7);
 
    bool b01 = f0 < f1;
    bool b12 = f1 < f2;
    bool b03 = f0 < f3;
    show(b01, b12, b03);
 
    Fraction f01 = min(f0, f1);
    Fraction f12 = min(f1, f2);
    Fraction f03 = min(f0, f3);
    show(string(f01), string(f12), string(f03));
     
    show(hash<Fraction>()(f12));
 
    return 0;
}

  执行结果:

1
2
3
4
5
6
7
8
201402
3 1.5 1.5
3/1 3/2 3/2
4.5 4.2
4.5 4.5 5.1
0 0 1
3/2 3/2 3/1
1.5

  

posted @   karinto  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示