您的位置:首页 > 其它

03_模板、类型转换、新数组、Lamdbda表达式、New高级用法

2017-05-17 15:13 441 查看
目录
一函数模板

二C类型转换

三C新数组三种

四Lamdbda表达式

五New高级用法

【目录】

一、 函数模板 2

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

一、函数模板

   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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐