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


相关文章
|
12月前
|
存储 算法 C++
【C++】——标准模板库STL作业(其一)
【C++】——标准模板库STL作业(其一)
【C++】——标准模板库STL作业(其一)
|
12月前
|
算法 C++ 容器
【C++】标准模板库STL作业(其二)
【C++】标准模板库STL作业(其二)
【C++】标准模板库STL作业(其二)
|
算法 C++
C++初阶作业 Vector作业详解
C++初阶作业 Vector作业详解
178 0
C++初阶作业 Vector作业详解
|
算法 C++ iOS开发
C++初阶作业 String类作业详解
C++初阶作业 String类作业详解
177 0
C++初阶作业 String类作业详解
|
前端开发 Java 数据库
软件工程个人作业2-四则运算2
四则运算 做题页 .aaa { text-align: center; font-weight: bold; } .
905 0
|
前端开发 Java 数据库
软件工程个人作业——四则运算
主页 要做的题数 首页 ...
1032 0
|
C++
2014秋C++ 第15周项目 指针基础
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目1-打入“内部”寻“内幕”】下面是一段使用了指针的程序。请利用“单步”执行的方式运行程序,深刻理解“指针变量存储的是地址值”、“通过指针变量间接访问”等概念。将在执行过程中留下深刻映像的界
1060 0
|
C++
2014秋C++第9周项目5参考-循环填充题
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703。课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目5:程序填充题】在程序中横线上填上恰当的成分,使完成题目要求的功能: 1.输出1000以内能被3整除且个位数为6的所有整数。 #include &lt;iostream&gt; using
1111 0
|
C++
2014秋C++第9周项目1参考-利用循环求和
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703。课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。   【项目1:利用循环求和】求1000以内所有偶数的和 要求:请编出3个程序来,分别用三种循环语句完成,注意体会各种循环语句的执行过程及语法特点。 参考解答://用for循环完成 #include &
1087 0
|
C++
2014秋C++第8周项目1参考-分段函数求值
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,实践要求见http://blog.csdn.net/sxhelijian/article/details/39493833。 课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。 【项目1:分段函数求值】 编程序,计算下面函数的值并输出(x取整型即可)
1221 0

热门文章

最新文章

下一篇
oss创建bucket