STL第五周作业

简介: Boolan  C++研发工程师课程的作业真是越往后越难了。学了两个月了,从小白走到现在,确实是提高了不少。笔芯侯捷老师。/*题目:设计一个Measurement计量单位类型,满足如下要求,1.

Boolan  C++研发工程师课程的作业真是越往后越难了。学了两个月了,从小白走到现在,确实是提高了不少。笔芯侯捷老师。

/*题目:
设计一个Measurement计量单位类型,满足如下要求,
1. 当为距离单位,当构造米或者千米等不同距离单位的实例时,统一以米为基本单位,
实例调用description函数返回单位对应的meter类型(米类型)
2. 当为时间单位,当构造分钟或者秒为单位的实例时,统一以秒为基本单位,
实例调用description函数返回单位对应的second类型(秒类型)
3. 如果为除距离和时间的其他单位,都打印值即可。

提示
请使用Traits来完成该题,通过Traits获取不同计量单位的转换系数 和 基本单位。

用sprintf()函数将一个变量从int类型转换到字符串类型
*/

#include "stdafx.h"
#include<iostream>
#include <iterator>
//<sstream>常用于格式转换,他定义了三种类:istringstream、ostringstream和stringstream
//分别用来进行流的输入、输出和输入输出操作。
#include <sstream>
/*
定义函数模板来将一个任意的类型转换到特定的目标类型
template<class T>
void to_string(string & result,const T& t)
{
    //创建一个流
    ostringstream oss;

    //把值传递如流中
    oss<<t;

    //使用str()成员函数来获取流内部缓冲的一份拷贝
    //获取转换后的字符转并将其写入result
    result=oss.str();
}
这样,你就可以轻松地将多种数值转换成字符串了:
to_string(s1,10.5);//double到string
to_string(s2,123);//int到string
to_string(s3,true);//bool到string
*/
using namespace std;

// 定义类型萃取机type_traits
template<typename T>
class type_traits
{
public :
	//将T::type_traits的类型名命名为valueType
	typedef typename T::type_traits valueType;
};

class meter {
private:
	string m_str;
public:
	//将meter类型改名为type_traits
	typedef meter type_traits;

	// 定义静态的转换系数
	static int m_convertData;
	//构造函数
	meter(string str) :m_str(str) {}
	//类型转换函数,为了在结尾加上单位
	meter(double val, int con = 1)
	{
		/*
		如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;
		在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。
		stringstream对象的构造和析构函数通常是非常耗费CPU时间的。
		stringstream的转换拥有类型安全和不会溢出的特性
		*/
		stringstream sstring;
		// 输入double类型数值,输出string类型数值
	    //输出值为:距离*转换系数
		sstring << val * con;
		sstring >> m_str;
		// 在输出值末尾加上基本单位
		m_str = m_str + "m";
	}
	//拷贝构造
	meter(meter& met)
	{
		//获取meter内的string数据
		m_str = met.m_str;
	}
	// 重载运算符<<,作用:想让cout输出非标准库中的类型,就要重载<<来使其可以识别自定义的类别
	friend ostream& operator<<(ostream& os, const meter& str)
	{
		//获取meter的私有string类型的数据m_str
		os << str.getSting();
		//将获取的数据返回
		return os;
	}
	string getSting() const
	{
		//返回meter的私有数据m_str
		return m_str;
	}
};

class kilometer {
public :
	//将meter的类型名命名为type_traits
	typedef meter type_traits;
	// 定义静态的转换系数
	static int m_convertData;
};

class second {
private:
	string m_str;	
public:
	//将second的类型名命名为type_traits
	typedef second type_traits;
	// 定义静态的转换系数
	static int m_convertData;
	//构造函数
	second(string str) :m_str(str) {}
	//类型转换
	second(double val, int con = 1)
	{
		stringstream sstring;
		//输入double类型值,输出string类型值
		sstring << val * con;
		sstring >> m_str;
		// 在输出值末尾加上基本单位
		m_str = m_str + "s";
	}
	//拷贝构造函数
	second(second& met)
	{
		m_str = met.m_str;
	}
	// 重载运算符<<,为了可以sout自定义类型
	friend ostream& operator<<(ostream& os, const second& str)
	{
		os << str.getSting();
		return os;
	}
	string getSting() const
	{
		return m_str;
	}
};

class minute {
public:
	//将second的类型名命名为type_traits
	typedef second type_traits;
	// 定义静态的转换系数
	static int m_convertData;
};

//传入参数的类型不确定,此时告知编译器传入的I是一个类型名
template<typename I>
class Measurement {
private:
	double value;
public:
	//构造函数
	Measurement(double val) :value(val) {}
	// 定义获取单位类型对应数值函数
	//函数的返回值类型为type_traits<I>::valueType,即萃取出的传入的类型参数I的类型
	typename type_traits<I>::valueType description()
	{
		//定义type_traits<I>::valueType的类名为valType
		//kilometer的valueType为meter,minute的valueType为second
		//因此kilometer类和minute类不需要写类型转换函数,也不需要重载<<
		typedef typename type_traits<I>::valueType valType;

		//获取不同计量单位的转换系数
		int iconv = I::m_convertData;
		//调用对应的自定义类中的类型转换函数
		valType typeVal(value, iconv);
		//返回带单位的string类型的字符串
		return typeVal;
	}
};

// 计量单位的泛化类型,因为传入的类名可能不是我们定义的类
template<>
//这里传入的是double类型,所以偏特化double
class Measurement<double>
{
private:
	double value;
public:
	//构造函数
	Measurement(double val) :value(val) {}
	//除距离和时间的其他单位,打印其值。
	string description()
	{
		stringstream sstring;
		string str;
		sstring << value;
		sstring >> str;
		return str;
	}
};

//为转化系数赋值
int meter::m_convertData = 1;
int kilometer::m_convertData = 1000;
int second::m_convertData = 1;
int minute::m_convertData = 60;

int main()
{

	Measurement<meter> m1 = 20;
	Measurement<kilometer> m2 = 11.2;
	//创建拷贝构造函数
	meter me = m1.description();
	Measurement<second> m3 = 20;
	Measurement<minute> m4 = 10;
	Measurement<double> m5 = 10;
	//想让cout输出非标准库中的类型,就要重载<<来使其可以识别自定义的类别
	cout << me << endl;
	cout << m2.description() << endl;
	cout << m3.description() << endl;
	cout << m4.description() << endl;
	cout << m5.description() << endl;
    return 0;
}


相关文章
|
算法 C++ iOS开发
C++初阶作业 String类作业详解
C++初阶作业 String类作业详解
157 0
C++初阶作业 String类作业详解
|
算法 C++
C++初阶作业 Vector作业详解
C++初阶作业 Vector作业详解
146 0
C++初阶作业 Vector作业详解
|
数据库
第八周课后作业 数据库查询练习
第八周课后作业 数据库查询练习
第八周课后作业 数据库查询练习
|
数据库 索引
第七周课后作业简单查询以及相关索引操作
第七周课后作业简单查询以及相关索引操作
第七周课后作业简单查询以及相关索引操作
|
C++ 搜索推荐
2014秋C++第16周 项目1参考 数组的排序
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目1-数组的排序】按给定部分程序的要求,用指向数组的指针变量作为形式参数编写函数,完成排序。重点体会:(1)排序算法,可以是冒泡,也可以是选择;(2)用指向数组的指针变量作为形式参数,用数组名
1034 0
|
C++
2014秋C++第16周 项目4参考 为动态数组扩容
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目4-为动态数组扩容】  下面的程序,利用动态数组保存学生的成绩。当再有一批学生成绩需要保存时,要为之扩容(和吃自助一样,用多少,取多少,这好),请补充完整下面的程序,实现如图所示的功能。 i
1121 0
|
C++
2014秋C++ 第15周项目 指针基础
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目1-打入“内部”寻“内幕”】下面是一段使用了指针的程序。请利用“单步”执行的方式运行程序,深刻理解“指针变量存储的是地址值”、“通过指针变量间接访问”等概念。将在执行过程中留下深刻映像的界
1043 0
|
物联网 C++ 人工智能
2014秋C++第13周项目4参考-数组的排序
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目4 - 数组的排序】(1)编写函数,完成冒泡排序,要求不能改变下面的main函数。 //两个函数bubble_sort和output_array的声明 int main( ) {
1073 0
|
C++ 人工智能
2014秋C++第13周项目5参考-字符串操作
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目5-字符串操作】(1)阅读下面的程序,完成类似的字符统计功能 #include&lt;iostream&gt; #include&lt;cstdio&gt; using namespac
1020 0
|
C++
2014秋C++第10周项目3参考-血型统计
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目3:血型统计】黑猫警长在犯罪现场发现了一些血迹,现已经委托检验机构确定了血型,需要统计各种血型的样本数目。输入:血型序列(A/B/O/C,C代表AB型血,输入以X结束)输出:各种血型的数量输入
1012 0