信息发布软件,b2b软件,广告发布软件
标题: 各种想扩展C++ 的大牛们就要会这些完美转换测试 [打印本页]
作者: 群发软件 时间: 2017-6-15 22:50
标题: 各种想扩展C++ 的大牛们就要会这些完美转换测试
本帖最后由 群发软件 于 2017-6-15 22:52 编辑
标准库包含了大量的函数和其他支持实体,增加和扩展了C++的基本语言功能。标准库的内容是C++的一部分,在语言的语法和语义方面跟C++相同。C++的标准定义了这两者,所以每个符合该标准的编译器都提供了完整的标准库。
标准库的范围是很特殊的。使用该标准库将获得非常多的功能,包括基本元素如基本语言支持、输入输出函数和异常处理(异常是在程序执行过程中发生的偶然事件,常常是某种错误),实用函数,数学例程和各种预先编写好并测试通过的功能。在程序执行过程中可借助这些功能来存储和管理数据。
要高效地使用C++,应非常熟悉标准库的内容。本书在介绍C++语言时,将讨论标准库的许多功能,但本书介绍的内容肯定是不完整的。要完整地介绍标准库的功能和用法,需要用与本书同样篇幅的另一本书来讨论。
使用标准库所需要的定义和声明位于前面介绍的标准头文件中。在一些情况下,标准头文件默认包含在程序文件中,但在大多数情况下,必须添加一个#include指令,把要使用的库功能所在的头文件包含进来。附录C中列出了一个完整的头文件列表,并简要说明了每个头文件支持的功能。
C++标准库中的几乎所有内容都是在命名空间std中定义的。也就是说,库中使用的所有名称都应加上前缀std。如本章前面所述,在引用标准库中的内容时,需要在名称前面加上前缀std,如下面的语句所示:
std::cout<<"The best place to start is at the beginning";
另外,也可以在源文件的开头加上一个using指令:
using namespace std;
这样,标准库名称就可以省略前缀std了,因为std中的所有名称在程序文件中都是自动可用的,所以上面的语句可以改写为:
cout<<"The best place to start is at the beginning";
在实际开发过程中,C++string类使用起来有很多不方便的地方,笔者根据根据这些不足简单的扩展了这个类,如增加与数字之间的相互转化和格式化字符串。不足的地方望指正。读者也可以根据自己需求继续扩展。
头文件:exstring.h
[cpp] view plain copy
- /*
- Author: wuqiang
- Email:
- Description:exstring is a subclass of basic_string.It is added some userful
- operations,such as toUpper,toLower,toNumber,fromNumber,format,etc.It can also
- convert between basic_string seamlessly,which is very important for compatibility.
- And it is almostly a wrapper of some C++ standard library,so there should be no bugs.
- If you find some,please let me known.It is totally free,you can use it in any way you desire.
- */
- #pragma once
-
- #include <string>
- #include <stdarg.h>
- #include <algorithm>
- #include <sstream>
- #include <iomanip>
-
- using namespace std;
-
- #ifndef INLINE
- #define INLINE inline
- #endif //INLINE
-
- static ios_base::fmtflags BaseFlag(int base)
- {
- return (base == 16) ? (ios_base::hex) :
- ( (base == 8) ? (ios_base:ct) : (ios_base::dec) );
- }
-
- template<class _Elem> struct ex_char_traits
- {
- };
-
- template<> struct ex_char_traits<char>
- {
- static INLINE int ct_vscprintf(const char* format, va_list argptr )
- {
- return _vscprintf(format, argptr);
- }
- static INLINE int ct_vstprintf_s(char* buffer, size_t numberOfElements,
- const char* format, va_list argptr)
- {
- return vsprintf_s(buffer, numberOfElements, format, argptr);
- }
- };
-
- template<> struct ex_char_traits<wchar_t>
- {
- static INLINE int ct_vscprintf(const wchar_t* format, va_list argptr )
- {
- return _vscwprintf(format, argptr);
- }
- static INLINE int ct_vstprintf_s(wchar_t* buffer, size_t numberOfElements,
- const wchar_t* format, va_list argptr)
- {
- return vswprintf_s(buffer, numberOfElements, format, argptr);
- }
- };
-
- template<class _Elem, class _Traits, class _Ax, class Type>
- Type ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- Type t, int base)
- {
- ss.setf(BaseFlag(base), ios_base::basefield);
- ss >> t;
- return t;
- }
-
- template<class _Elem, class _Traits, class _Ax>
- float ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- float t, int/*ignore base*/)
- {
- ss >> t;
- return t;
- }
-
- template<class _Elem, class _Traits, class _Ax>
- double ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- double t, int/*ignore base*/)
- {
- ss >> t;
- return t;
- }
-
- template<class _Elem, class _Traits, class _Ax, class _ExTraits>
- class basic_exstring : public basic_string<_Elem, _Traits, _Ax>
- {
- public:
- typedef basic_exstring<_Elem, _Traits, _Ax, _ExTraits> _Myt;
- typedef basic_string<_Elem, _Traits, _Ax> _Mybase;
-
- #pragma region "constructor"
-
- //所有构造函数的行为同basic_string
-
- explicit INLINE _Myt(const _Ax& al = _Ax())
- :_Mybase(al)
- {
- }
- INLINE _Myt(const _Myt& rhs)
- :_Mybase(rhs)
- {
- }
- INLINE _Myt(const _Myt& rhs, size_type pos, size_type n,const _Ax& al = _Ax())
- :_Mybase(rhs, pos, n, al)
- {
- }
- INLINE _Myt(const _Elem *s, size_type n, const _Ax& al = _Ax())
- :_Mybase(s, n, al)
- {
- }
- INLINE _Myt(const _Elem *s, const _Ax& al = _Ax())
- :_Mybase(s, al)
- {
- }
- INLINE _Myt(size_type n, _Elem c, const _Ax& al = _Ax())
- :_Mybase(n, c, al)
- {
- }
- INLINE _Myt(const_iterator first, const_iterator last,const _Ax& al = _Ax())
- :_Mybase(first, last, al)
- {
- }
-
- //string(wstring)转化为exstring(exwstring)
- INLINE _Myt(const _Mybase& base)
- :_Mybase(base)
- {
-
- }
- #pragma endregion //constructor
-
-
- #pragma region "general operation"
-
- //所有字符转为大写,改变自身
- _Myt& toUpper()
- {
- transform(begin(), end(), begin(), toupper);
- return *this;
- }
-
- //所有字符转为大写,不改变自身
- _Myt toUpper() const
- {
- _Myt s;
- transform(begin(), end(), s.begin(), toupper);
- return s;
- }
-
- //所有字符转为小写,改变自身
- _Myt& toLower()
- {
- transform(begin(), end(), begin(), tolower);
- return *this;
- }
-
- //所有字符转为大写,不改变自身
- _Myt toLower() const
- {
- _Myt s(_Mysize, _Elem());
- transform(begin(), end(), s.begin(), tolower);
- return s;
- }
-
- //将所有oldStr替换为newStr
- _Myt& replace(const _Myt& oldStr, const _Myt& newStr)
- {
- if (oldStr.empty())
- return *this;
- size_type index;
- while ( (index = find(oldStr)) != npos )
- _Mybase::replace(index, oldStr.size(), newStr);
- return *this;
- }
-
- //删除左边所有包含在target中的字符
- _Myt& trimLeft(const _Myt& target)
- {
- while (!empty() && (target.find(*begin()) != npos))
- erase(begin());
- return *this;
- }
-
- //删除右边所有包含在target中的字符
- _Myt& trimRight(const _Myt& target)
- {
- while (!empty() && target.find(*rbegin()) != npos)
- erase(--end());
- return *this;
- }
-
- //返回左边count个字符,count大于总长度则返回整个字符串
- _Myt left(size_type count) const
- {
- return substr( 0, count );
- }
-
- //返回右边count个字符,count大于总长度则返回整个字符串
- _Myt right(size_type count) const
- {
- return substr( _Mysize < count ? 0 : _Mysize - count );
- }
-
- //忽略大小写判断两个字符串是否相等
- int compareNoCase(const _Myt& rhs) const
- {
- return toLower().compare(rhs.toLower());
- }
-
- //判断字符串是否以制定字符串开头
- bool beginWith(const _Myt& rhs) const
- {
- return find(rhs) == size_type(0);
- }
-
- //判断字符串是否以制定字符串结尾
- bool endWith(const _Myt& rhs) const
- {
- if(rhs.size() > _Mysize)
- return false;
- return compare(_Mysize - rhs.size(), rhs.size(), rhs) == 0;
- }
- #pragma endregion //general operation
-
-
- #pragma region "convert between numbers"
-
- //将字符串转为数字
- //base:进制数。可以为8,10,16,如果其它值则强制为10。浮点数则忽略此参数
- template<typename T>
- T toNumber (int base = 10) const
- {
- T t = T();
- basic_stringstream<_Elem, _Traits, _Ax> ss(_Myptr());
- return ConvertToNumber<_Elem, _Traits, _Ax>(ss, t, base);
- }
-
- //将整数转化为字符串
- //base:进制数。可以为8,10,16,如果其它值则强制为10
- template<typename T>
- static _Myt fromNumber ( T number, int base = 10 )
- {
- basic_stringstream<_Elem, _Traits, _Ax> ss;
- ss.setf(BaseFlag(base), ios_base::basefield);
- ss << number;
- return ss.str();
- }
-
- //将float转化为字符串
- //f:格式化参数。可以为'f','e','E','g','G'。'f'为定点数,'e'或'E'表示科学计数法
- // 'g'或‘G’表示格式化为定点数或科学计数法,看哪一个表示方便。
- //prec:小数点后的位数(定点数表示法)或总的有效位数(科学计数法)
- static _Myt fromNumber ( float number, _Elem f = _Elem('g'), int prec = 6 )
- {
- return fromNumber(static_cast<double>(number), f, prec);
- }
-
- //将double转化为字符串,参数解释同上
- static _Myt fromNumber ( double number, _Elem f = _Elem('g'), int prec = 6 )
- {
- basic_stringstream<_Elem, _Traits, _Ax> ss;
- ss << setprecision(prec);
- if ( _Traits::eq(f, _Elem('f')) )
- ss << setiosflags(ios_base::fixed);
- else if ( _Traits::eq(f, _Elem('e')) || _Traits::eq(f, _Elem('E')) )
- ss << setiosflags(ios_base::scientific);
- ss << number;
- return ss.str();
- }
- #pragma endregion //convert between numbers
-
-
- #pragma region "format string"
-
- //将szFormat格式化为字符串,参数解释同sprintf
- void format(const _Elem* szFormat, ...)
- {
- if(!szFormat)
- return;
- va_list argList;
- va_start(argList, szFormat);
- formatV(szFormat, argList);
- va_end(argList);
- }
-
- //将szFormat格式化为字符串,参数解释同sprintf
- void formatV(const _Elem* szFormat, va_list argList)
- {
- if(!szFormat)
- return;
- int nLength = _ExTraits::ct_vscprintf(szFormat, argList);
- if(nLength < 0)
- return;
- resize(nLength);
- _ExTraits::ct_vstprintf_s(_Myptr(), nLength + 1, szFormat, argList);
- va_end(argList);
- }
- #pragma endregion //format string
- };
-
- typedef basic_exstring<char, char_traits<char>,
- allocator<char>, ex_char_traits<char> > exstring;
-
- typedef basic_exstring<wchar_t, char_traits<wchar_t>,
- allocator<wchar_t>, ex_char_traits<wchar_t> > exwstring;
使用举例:
[cpp] view plain copy
- #include <iostream>
- #include <tchar.h>
- #include "exstring.h"
-
- #ifdef _UNICODE
- typedef exwstring tstring;
- #define tcout wcout
- #else
- typedef exstring tstring;
- #define tcout cout
- #endif //_UNICODE
-
- int main(int argc, char* argv[])
- {
- tstring s(_T("\t Hello ExString\r\n"));
- tcout << _T("result of triming left:") << s.trimLeft(_T("\t ")) << endl;
- tcout << _T("result of triming right:") << s.trimRight(_T("\r\n")) << endl;
- tcout << _T("result of compare") << s.compareNoCase(_T("hello exstring")) << endl;
- tcout << _T("result of converting to upper:") << s.toUpper() << endl;
- tcout << _T("result of converting to lower:") << s.toLower() << endl;
-
- tcout << _T("the left 5 chars:") << s.left(5) << endl;
- tcout << _T("the right 8 chars:") << s.right(8) << endl;
- tcout << _T("result of appending:") << s.append(_T(",exstring is practical")) << endl;
- tcout << _T("result of replacing:") << s.replace(_T("exstring"), _T("Exstring")) << endl;
-
- s.format(_T("sizeof(%s) is %d(0x%x)"), _T("exstring"), sizeof(exstring), sizeof(exstring));
- tcout << _T("result of formating:") << s << endl;
-
- tcout << tstring(_T("0xFF")).toNumber<int>(16) << endl;
- tcout << tstring(_T("-1")).toNumber<unsigned __int64>() << endl;
- tcout << tstring(_T("12.3456789")).toNumber<float>() << endl;
-
- tcout << tstring::fromNumber(255) << endl;
- tcout << _T("0x") << tstring::fromNumber(__int64(-1), 16).toUpper() << endl;
- tcout << tstring::fromNumber(12.3456789, _T('f'), 4) << endl;
- tcout << tstring::fromNumber(12.3456789, _T('E'), 4) << endl;
-
- return 0;
- }
输出:
问题抛出:
1. C++编译时如何区分是c1对象,c2对象还是c3对象调用了类的方法
2. class类是一个数据类型,和对象之间是1:n关系
3. 学习c++的方法是和面向过程不一样的
c++对c的扩展:
1.面向对象概念(cout cin类、对象 面向对象和面向过程求解问题)
2.易犯错误模型(引入成员函数的必要性)
[cpp] view plain copy
- class Cycle{
- public:
- double radius;
- double pi=3.14;
- double area=pi*radius*radius;
- }
- void main(){
- Cycle ci;
- ci.radius=2;
- cout<<ci.area<<endl;//此时输出的是随机值,因为当构建Cycle对象时,就已经给area初始化了
- }
[cpp] view plain copy
- class Cycle{
- public:
- double radius;
- double pi=3.14;
- double area=pi*radius*radius;
- }
- void main(){
- Cycle ci;
- ci.radius=2;
- cout<<ci.area<<endl;//此时输出的是随机值,因为当构建Cycle对象时,就已经给area初始化了
- }
3.C语言和C++语言的关系
4.namespace定义(可嵌套)、使用、标准命名空间std、iostream中没有引入std
5.实用性增强(变量定义)、全局变量定义检查、变量类型检查严格(C语言中允许对变量进行二定义,C++不允许)、所有变量和函数定义必须有类型
[cpp] view plain copy
- //在C语言中
- int f();//表示返回值为int,接受任意参数的函数
- int f(void);//表示返回值为int 的无参函数
- //在C++中
- //int f()和int f(void)具有相同的意义,都表示返回值为int的无参函数
[cpp] view plain copy
- //在C语言中
- int f();//表示返回值为int,接受任意参数的函数
- int f(void);//表示返回值为int 的无参函数
- //在C++中
- //int f()和int f(void)具有相同的意义,都表示返回值为int的无参函数
6.register功能增强,c中不能取地址,c++优化
7.struct关键字(c中不是新类型,如果要当做数据类型使用,必须前面加上 struct ),与class功能相同
8.类型加强bool 1个字节,但只有true和false
9.c++中三目运算符 返回变量自身 c中返回的是变量的值 ,因此不能为左值
[cpp] view plain copy
- int main(){
- int a=10;
- int b=20;
- int var=100;
- var=101;
- //返回一个最小数,并且给最小数赋值成3
- //在C语言中,三目运算符是一个表达式,表达式不能做左值,但是可做如下修改,达到跟C++语言相同的效果
- *(a<b?&a:&b)=3;
- return 0;
-
- }
[cpp] view plain copy
- int main(){
- int a=10;
- int b=20;
- int var=100;
- var=101;
- //返回一个最小数,并且给最小数赋值成3
- //在C语言中,三目运算符是一个表达式,表达式不能做左值,但是可做如下修改,达到跟C++语言相同的效果
- *(a<b?&a:&b)=3;
- return 0;
-
- }
const:
1.基础知识(指针变量和它所指向的空间变量是两个不同的概念)
[cpp] view plain copy
- const int a;
- int const b; //一样
-
- const int *c; //const修饰的是指针所指向的内存空间,不能被修改
- int * const d; //
- const int * const e ;
[cpp] view plain copy
- const int a;
- int const b; //一样
-
- const int *c; //const修饰的是指针所指向的内存空间,不能被修改
- int * const d; //
- const int * const e ;
2.c中冒牌货(只读变量,有自己存储空间)
[cpp] view plain copy
- void main(){
- const int a=10;//好像a是一个常量
- int *p=NULL;
- p=(int *)&a;
- *p=20;//间接赋值
-
- }
[cpp] view plain copy
- void main(){
- const int a=10;//好像a是一个常量
- int *p=NULL;
- p=(int *)&a;
- *p=20;//间接赋值
-
- }
3.c++中const的符号表实现机制,不同于c语言中的const,c中的const是假的,可通过指针来修改其指向的值
[cpp] view plain copy
- /*解释
- C++编译器对const常量的处理,当碰见常量声明时,在符号表中放入常量,类似于键值对key->value。那有如何解释取地址的问题。
- 编译过程中若发现使用常量则直接以符号表中的值替换。
- 编译过程中若发现对const使用了extern或&操作符,则给对应的常量分配存储空间,但是与符号表没有任何关系,因此,也改变不了const变量的值。
- */
[cpp] view plain copy
- /*解释
- C++编译器对const常量的处理,当碰见常量声明时,在符号表中放入常量,类似于键值对key->value。那有如何解释取地址的问题。
- 编译过程中若发现使用常量则直接以符号表中的值替换。
- 编译过程中若发现对const使用了extern或&操作符,则给对应的常量分配存储空间,但是与符号表没有任何关系,因此,也改变不了const变量的值。
- */
4.const常量是由编译器处理的,提供类型检查和作用域检查
5.#define宏定义由预处理器处理,单纯的文本替换,没有作用域这一说
6.const修饰类成员变量(构造函数初始化列表)
7.const修饰类成员函数:修饰的是this指针
引用:
1.引用概念,给变量起一个别名,本质是给内存空间取个别名
2.引用是c++的语法概念、引用的意义(好用)
3.引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量
4.引用结论: 间接赋值成立的三个条件的后两步合二为一
5.引用使用原则:当用引用时,我们不去关系编译器引用是怎么做的;当分析奇怪的语法现象时,才去考虑c++编译器是怎么做的。
6.函数返回值是引用(若返回栈变量,不能成为其他引用的初始化,此时函数调用后,已经释放掉该栈空间)
7.函数返回值当左值,必须返回一个引用(返回的是变量本身)
作者: w8899 时间: 2017-6-22 16:38
强大,使用简单便捷,真心的不错,卖家发货速度快,赞。
作者: 大宝罗滴滴 时间: 2017-6-22 19:07
作有些小插曲,通过充分沟通,店家积极用心的帮忙解决了问题。设计是非标准的产品,设计和客户之间的沟通非常重要
作者: 乱世扶稣 时间: 2017-6-22 20:05
耐心的给我讲解,远程指导、安装,非常棒的老板,网站也是贼亮的,满分
作者: 小白 时间: 2017-6-24 20:01
服务那是相当的好啊太好了的如果客服是女的我准备取她做媳妇的
作者: java12005 时间: 2017-6-25 16:23
件超级实用,款式很多,能够满足建各种类型的网站的需求
作者: ekmci 时间: 2017-6-25 20:06
模板真心的不错显示工整完美大方使用简单方便之前用的是淘宝基础版枯燥不堪用了这模板后看自己的铺面心情都不样呵呵!店家的服务也非常周到有问必答而且非常有耐心省时省事省心。
作者: zdxhz 时间: 2017-7-3 12:10
棒哒,人品超好
作者: jh134724 时间: 2017-7-3 12:50
好,与卖家描述的完全一致,非常满意
作者: iiiiik 时间: 2017-7-7 08:50
笨蛋和5号笨蛋的服务,全五分好评。
作者: jskf10 时间: 2017-7-8 10:04
心,讲解很好,5分好评
作者: q1598188 时间: 2017-7-11 23:27
慢学~
欢迎光临 信息发布软件,b2b软件,广告发布软件 (http://postbbs.com/) |
Powered by Discuz! X3.2 |