03_模板、类型转换、新数组、Lamdbda表达式、New高级用法
2017-05-17 15:13
441 查看
目录
一函数模板
二C类型转换
三C新数组三种
四Lamdbda表达式
五New高级用法
1、 函数包装器 2
2、 函数模板覆盖 2
3、 函数模板重载(与指针密切配合)调用规则 3
4、 可变参数不限类型的函数模板 3
5、 函数模板重载 4
二、 C++类型转换 5
1、 static_cast<>():基本类型转换 5
2、 const_cast<>():常量属性去除 5
3、 reinterpret_cast<>():指针类型转换 5
4、 dynamic_cast<>():类类型转换 5
三、 C++新数组三种 5
1、 std::arrar ; 静态数组,栈上,大小不能超过1兆 5
2、 std::vector ; 动态数组,堆上 6
3、 Std::tuple ;多元数组,数组中的元素可以是不同类型的 6
4、 二维数组: 6
5、 正向迭代器: 6
6、 反向迭代器 7
7、 数组增删改查 7
8、 无规则动态管理数组 8
四、 Lamdbda表达式 8
五、 New高级用法 8
①.第一,设计执行接口,接口设计关卡(),计数;
②.第二,函数包装器依赖于函数模板,实现通用泛型;
③.第三,函数代码可以内嵌在另外一个函数,实现函数怀孕;
④.第四,函数包装器,用于管理内嵌函数,外部函数调用
2、函数模板覆盖
①.程序中有一个通用模板,在处理特定函数时,不能针对性处理。所以要针对某个参数的类型重写一个模板,在程序调用时就不会去调用通用模板,而是调用特定参数的模板。
3、函数模板重载(与指针密切配合)调用规则
4、可变参数不限类型的函数模板(错)
5、函数模板重载
6、函数模板引用无效,引用函数包装器
①.std::ref(变量名)
2、const_cast<>():常量属性去除
3、reinterpret_cast<>():指针类型转换
专业转换指针,最安全
4、dynamic_cast<>():类类型转换,父子类之间
这个以后写
2、std::vector ; 动态数组,堆上
3、Std::tuple ;多元数组,数组中的元素可以是不同类型的
4、二维数组:
5、正向迭代器:
6、反向迭代器
7、数组增删改查
8、无规则动态管理数组
一函数模板
二C类型转换
三C新数组三种
四Lamdbda表达式
五New高级用法
【目录】
一、 函数模板 21、 函数包装器 2
2、 函数模板覆盖 2
3、 函数模板重载(与指针密切配合)调用规则 3
4、 可变参数不限类型的函数模板 3
5、 函数模板重载 4
二、 C++类型转换 5
1、 static_cast<>():基本类型转换 5
2、 const_cast<>():常量属性去除 5
3、 reinterpret_cast<>():指针类型转换 5
4、 dynamic_cast<>():类类型转换 5
三、 C++新数组三种 5
1、 std::arrar ; 静态数组,栈上,大小不能超过1兆 5
2、 std::vector ; 动态数组,堆上 6
3、 Std::tuple ;多元数组,数组中的元素可以是不同类型的 6
4、 二维数组: 6
5、 正向迭代器: 6
6、 反向迭代器 7
7、 数组增删改查 7
8、 无规则动态管理数组 8
四、 Lamdbda表达式 8
五、 New高级用法 8
一、函数模板
1、函数包装器①.第一,设计执行接口,接口设计关卡(),计数;
②.第二,函数包装器依赖于函数模板,实现通用泛型;
③.第三,函数代码可以内嵌在另外一个函数,实现函数怀孕;
④.第四,函数包装器,用于管理内嵌函数,外部函数调用
#include <iostream> #include<functional> template<typename T , class F> T get( T t , F f){ static int count = 0 ; /*计数器*/ count++ ; std::cout<<"count--->"<<count<<std::endl ; /*其实这里实现函数劫持的效果*/ if (count > 1) { T vx(0); return vx; } return f(t) ; } template<typename T , class F> T get( T t1 , T t2 , F f ) { return f(t1,t2); } int cheng( int a , int b ) { return a*b ; } int main( int argc , char** argv ) { using namespace std ; int num = 3 ; /*实现函数的嵌套*/ function<int(int)> fun1 = [](int x){ return x*2 ; }; cout << get( num , fun1 ) << endl ; cout << get( num , fun1 ) << endl ; /*相当于一个函数指针外部函数调用*/ function<int(int,int)> fun2 = cheng ; cout << get( 5 , 6 , fun2 ) << endl ; system("pause") ; return 0 ; }
2、函数模板覆盖
①.程序中有一个通用模板,在处理特定函数时,不能针对性处理。所以要针对某个参数的类型重写一个模板,在程序调用时就不会去调用通用模板,而是调用特定参数的模板。
template<typename T> void 129a6 swap( T &t1 , T &t2 ) { std::cout << "通用函数模板" << std::endl; T temp = t1 ; t1 = t2 ; t2 = temp ; } class chen { public: int age ; }; /*模板为空,明确类型*/ template<> void swap( chen &c1 , chen &c2 ) { std::cout << "特有函数模板" << std::endl; /*通用模板可以实现通用,针对自己的数据类型做出优化*/ chen temp = c1; c1 = c2; c2 = temp; } int main( int argc , char** argv ) { int num1 = 5 ; int num2 = 6 ; swap(num1,num2) ; std::cout<<num1<<"---"<<num2<<std::endl ; /*------------------------*/ chen c1 , c2 ; c1.age = 10 ; c2.age = 20 ; swap(c1,c2) ; std::cout<<c1.age<<"---"<<c2.age <<std::endl ; }
3、函数模板重载(与指针密切配合)调用规则
template<typename T> T add( T t1 , T t2 ) { std::cout<<"T"<<std::endl ; return t1+t2 ; } int add(int a , int b) { std::cout<<"int"<<std::endl ; return a+b ; } int main( int argc , char** argv ) { std::cout<<add(1,2)<<std::endl ; /*<int>明确申明模板的类型*/ std::cout<<add<int>(1,2)<<std::endl ; /*这里明确了模板的类型,所以直接调用通用模板*/ std::cout<<add(1.0,2.2)<<std::endl ; }
4、可变参数不限类型的函数模板(错)
/*通用可变参数模板 处理不限定个数的参数,处理不同类型*/ void showall()/*空函数,接口,最后结束递归 新版本编译*/ { } template<typename T,typename...Args> void showall(const T &value, const Args &...args) { std::cout << value << std::endl; showall(args...);//继续传递 } //设计可以修改原来的数据的 T &value, Args &...args //设计可以修改副本 T value, Args ...args //设计不可以可以改原来的数据不可以修改副本 const T value, const Args ...args //设计引用原来的数据不可以修改 const T &value, const Args &...args void main(){ int num1 = 10, num2 = 9, num3 = 11; double db1 = 10.8, db2 = 10.9; char str[40] = "yincheng"; char ch = 'A'; showall(num1); std::cout << "\n\n\n"; showall(num1,num2,num3); std::cout << "\n\n\n"; showall(db1, db2, num1, ch); std::cout << "\n\n\n"; showall(db1, db2, num1, ch,str); std::cin.get(); }
5、函数模板重载
template<typename T> void showarray( array<T,10> myarray,int n ) { using namespace std; cout << "TTTTT" << endl; for (int i = 0; i < n;i++) { cout << myarray[i] <<" "; } cout << endl; } template<typename T> void showarray( array<T*, 10> myarray, int n ) { using namespace std; cout << "T*T*T*T*T*" << endl; for (int i = 0; i < n; i++) { cout << *myarray[i] << " "; } cout << endl; } void main() { array<int, 10> intarray = { 1, 2, 3, 4, 5,6,7,8,9,10 }; array<int*, 10> pintarray ; for (int i = 0; i < 10; i++) { pintarray[i] = &intarray[i]; } array<int**, 10> ppintarray; for (int i = 0; i < 10; i++) { ppintarray[i] = &pintarray[i]; } showarray(intarray, 10); showarray(pintarray, 10); showarray(ppintarray, 10); std::cin.get(); }
6、函数模板引用无效,引用函数包装器
①.std::ref(变量名)
#include<iostream> template<typename T> void get(T t) { t++ ; } int main( int argc , char** argv ) { int num = 10 ; get(num) ; std::cout<<num<<std::endl ; int &rnum = num ; get( rnum ) ;/*模板函数引用无效*/ std::cout<<num<<std::endl ; get( std::ref(num) ) ;/*必须使用引用函数包装器*/ std::cout<<num<<std::endl ; std::cin.get() ; return 0 ; }
二、C++类型转换
1、static_cast<>():基本类型转换int n = static_cast<int>(78.98);
2、const_cast<>():常量属性去除
int age = 22 ; const int *page = &age ; /*去除const属性*/ Int *pnew = const_cast<int *>( page ) ;
3、reinterpret_cast<>():指针类型转换
专业转换指针,最安全
int num = 1234 ; char *p = reinterpret_cast<char *>(&num) ; for( int i=0 ; i<4 ; i++ ) { printf("%c,%d,%p\n", *(p+i), *(p+i), p+i); }
4、dynamic_cast<>():类类型转换,父子类之间
这个以后写
三、C++新数组三种
1、std::array ; 静态数组,栈上,大小不能超过1兆/*std::array数据类型,int元素类型,3个数*/ std::array<int,3> inew = {1,2,3} ; for( auto i : inew ){ std::cout<<i<<std::endl ; } std::array<std::string ,3> istring = { "chen" , "wei" , "nan" } ; for( auto i : istring ){ std::cout<<i.c_str()<<std::endl ; }
2、std::vector ; 动态数组,堆上
std::vector<int> myvector ; for( int i=0 ; i<1024*1024 ; i++ ) { myvector.push_back(i) ; //string1.pop_back();//删除一个 //string1.clear();//清空 }
3、Std::tuple ;多元数组,数组中的元素可以是不同类型的
void main(void) { int int1 = 10; double double1 = 99.8; char ch = 'A'; char *str = "hellochina"; std::tuple<int, double, char, const char *> mytuple(int1, double1, ch, str); const int num = 3; auto data0 = std::get<0>(mytuple); auto data1 = std::get<1>(mytuple); auto data2 = std::get<2>(mytuple); auto data3 = std::get<num>(mytuple);//下标只能是常量 std::cout <<typeid( data3).name() << std::endl; decltype(data0) dataA;//获取数据类型再次创建 //mytuple.swap(mytuple);array.vetor都有交换的公能 std::cout << data0 <<" " << data1 <<" "<< data2 << " " <<data3 << std::endl; std::cin.get(); } //tuple必须是一个静态数组, //配合vector, array
4、二维数组:
std::array<int, 5> myint1 = { 1, 2, 3, 4, 5 }; std::array<int, 5> myint2 = { 11, 12, 13, 14, 15 }; std::array<int, 5> myint3 = { 21, 22, 23, 24, 25 }; std::array<std::array<int, 5>, 3> myint = {myint1,myint2,myint3}; std::array<std::array<int, 5>, 3> myint = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; for (int i = 0; i < myint.size();i++) { for (int j = 0; j < myint1.size(); j++) { std::cout << " "<<myint[i][j]; } std::cout << "\n"; }
5、正向迭代器:
std::array<int, 5> myint = { 1, 2, 3, 4, 5 }; std::array<int,5>::iterator ibegin , iend ; ibegin = myint.begin() ; iend = myint.end() ; while( ibegin != iend ) { std::cout<<*ibegin<<std::endl ; ibegin++ ; } std::vector<std::string> mystring ; mystring.push_back("chen") ; mystring.push_back("wei") ; mystring.push_back("nan") ; std::vector<std::string>::iterator sbegin , send ; sbegin = mystring.begin() ; send = mystring.end() ; while( sbegin != send ){ std::cout<<(*sbegin).c_str()<<std::endl ; sbegin++ ; }
6、反向迭代器
std::array<int, 5> myint = { 1, 2, 3, 4, 5 }; std::array<int,5>::reverse_iterator ibegin , iend ; ibegin = myint.rbegin() ; iend = myint.rend() ; while( ibegin != iend ) { std::cout<<*ibegin<<std::endl ; ibegin++ ; } std::vector<std::string> mystring ; mystring.push_back("chen") ; mystring.push_back("wei") ; mystring.push_back("nan") ; std::vector<std::string>::reverse_iterator sbegin , send ; sbegin = mystring.rbegin() ; send = mystring.rend() ; while( sbegin != send ){ std::cout<<(*sbegin).c_str()<<std::endl ; sbegin++ ; }
7、数组增删改查
std::vector<int> myint ; myint.clear() ;/*删除所有元素*/ myint.push_back(3) ; myint.push_back(4) ; myint.push_back(5) ;/*在链表的末尾加上一个元素*/ myint.pop_back() ; /*弹出:删除最后一个元素*/ myint.insert( myint.begin()+1,66) ; /*增:任意位置插入*/ myint.erase( myint.begin()+2 ) ;/*删:任意位置删除*/ for( int i=0 ; i<myint.size() ; i++ ) { if( myint.at(i)==3 ) { /*查改*/ myint[i] = 33 ; } std::cout<<myint.at(i)<<"---"<<myint[i] <<std::endl ; }
8、无规则动态管理数组
std::vector<int> myint1 ; myint1.push_back(1) ; myint1.push_back(2) ; myint1.push_back(3) ; std::vector<int> myint2 ; myint2.push_back(11) ; std::vector<int> myint3 ; myint3.push_back(21) ; myint3.push_back(22) ; std::vector<std::vector<int>> myint ; myint.push_back( myint1) ; myint.push_back( myint2) ; myint.push_back( myint3) ; for( int i=0 ; i<myint.size() ; i++ ) { for( int j=0 ; j<myint[i].size() ; j++ ) { std::cout<<myint[i][j]<<" " ; } std::cout<<std::endl ; }
四、Lamdbda表达式
#include<iostream> #include<vector> #include<algorithm>算法 lambda表达式,不仅仅适用与array ,也适用于vector void main() { std::vector<int> myvector; myvector.push_back(11); myvector.push_back(22); myvector.push_back(33); int res=0;//结果 //&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码 std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; }); std::cout << res; std::cin.get(); Return 0 ; }
五、New高级用法
#include<iostream> #include<new> const int buf(512);//限定一个常量整数512 int N(5);//数组的长度 char buffer[buf] = {0};//静态区 //p1,p3,p5作为指针变量在栈区,存储的地址指向堆区 //手动释放内存 //p2,p4,p6作为指针变量在栈区,存储的地址在静态区。缓冲区。 //自动释放内存,用于分配用完了就不会再用的数据 //避免内存泄漏,自动释放内存。牺牲了内存访问独立性, using namespace std; void main() { double *p1, *p2; std::cout << "\n\n\n"; p1 = new double ;//分配内存,N个元素的大小 p2 = new (buffer)double ;//指定区域分配内存 for (int i = 0; i < N; i++) { p1[i] = p2[i] = i + 10.8;//对于数组初始化 std::cout << "p1=== " << &p1[i] << " " << p1[i]; std::cout << " p2=== " << &p2[i] << " " << p2[i] << std::endl; } double *p3, *p4; std::cout << "\n\n\n"; p3 = new double ;//分配内存,N个元素的大小 p4 = new (buffer)double ;//指定区域分配内存 for (int i = 0; i < N; i++) { p3[i] = p4[i] = i + 10.8 ;//对于数组初始化 std::cout << "p3=== " << &p3[i] << " " << p3[i]; std::cout << " p4=== " << &p4[i] << " " << p4[i] << std::endl; } double *p5, *p6; std::cout << "\n\n\n"; p5 = new double ;//分配内存,N个元素的大小 p6 = new (buffer)double ;//指定区域分配内存 for (int i = 0; i < N; i++) { p6[i] = p5[i] = i + 10.8;//对于数组初始化 std::cout << "p5=== " << &p5[i] << " " << p5[i]; std::cout << " p6=== " << &p6[i] << " " << p6[i] << std::endl; } std::cin.get(); }
相关文章推荐
- $.toJSON的用法或把数组转换成json类型(转)
- JNI数组类型转换遇到问题及解决(new jdouble(len)与new jdouble[len]的区别)
- 细嚼慢咽C++primer(2)——表达式,sizeof,new,delete,类型转换
- $.toJSON的用法或把数组转换成json类型
- $.toJSON的用法或把数组转换成json类型
- 第五章 表达式(part3) 复合表达式的求值、new 和 delete 表达式、类型转换
- Go各种类型转换及函数的高级用法
- AJAX $.toJSON的用法或把数组转换成json类型
- 【C/C++学院】0825-类模板/final_override/类模板与普通类的派生类模板虚函数抽象模板类/类模板友元/位运算算法以及类声明/Rtti 实时类型检测/高级new创建/类以及函数包装器
- $.toJSON的用法或把数组转换成json类型
- 二十、运算符重载(四) Integer类改进、类型转换运算符重载、 ->运算符重载、 new的三种用法、operator new、operator delete重载
- 细嚼慢咽C++primer(2)——表达式,sizeof,new,delete,类型转换
- AJAX $.toJSON的用法或把数组转换成json类型
- c#中数组,类型转换,using语句的其他用法
- 将基础数据类型与字节数组相互转换
- 只能使用数组初始值设定项表达式为数组类型赋值。请尝试改用新的表达式
- C++风格的类型转换的用法
- 时间类型的转换,SQL中CONVERT转化函数的用法 (转载)
- 字符串数组类型的object,如何转换为string[],
- string数组类型转换为int数组(数组类型之间的转换)