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

//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...);
}

  

//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;
}

  执行结果:

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 @ 2023-02-27 00:38  karinto  阅读(75)  评论(0)    收藏  举报