提高篇
类型转换:
- static_cast 用于内置数据类型、具有继承关系的指针类型、具有继承关系的引用转换
- dynamic_cast 通常在基类和及派生类转换时使用
- const_cast 主要针对const和非const的转换
- reinterpret_cast 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整型数
示例:
#include<iostream>
using namespace std;
class Building
{};
class Animal
{
};
class Cat :public Animal
{
};
//1、static_cast 用于内置数据类型、具有继承关系的指针类型、具有继承关系的引用转换
void _01Test01()
{
//用于内置数据类型
int a = 97;
char c = static_cast<char>(a);
cout << c << endl;
//用于具有继承关系的指针
Animal* animal1 = NULL;
Cat* cat1 = static_cast<Cat*>(animal1);
Cat *cat2=NULL;
Animal *animal2 = dynamic_cast<Animal*>(cat2);
//用于具有继承关系的引用
Animal ani;
Animal& animal11 = ani;
Cat& cat11 = static_cast<Cat&>(animal11);
Cat ca;
Cat& cat22 = ca;
Animal& animal22 = static_cast<Animal&>(cat22);
}
//2、dynamic_cast 通常在基类和及派生类转换时使用,在转换前会进行对象类型检查
void _01Test02()
{
//父类指针转为子类指针会造成访问错误
//子类指针可以转为父类指针
Cat* cat = NULL;
Animal* animal = dynamic_cast<Animal*>(cat);
}
//3、const_cast 主要针对const和非const的转换
void _01Test03()
{
//基本数据类型
int a = 10;
const int& b =a;//非const转化为const
int& c = const_cast<int &>(b);//const转化为非const
c = 20;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "c:" << c << endl;
//指针
int* p1=NULL;
const int* p2 = p1;//非const转化为const
int* p3 = const_cast<int*>(p2);//const转化为非const
}
//4、reinterpret_cast 强制类型转换 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整型数
typedef int(*FUN1)(int, int);
typedef int(*FUN2)(int,char);
void _01Test04()
{
//1、无关类型的指针都可进行转换
Building* build = NULL;
Animal* animal = reinterpret_cast<Animal*>(build);
//2、函数指针转换
FUN1 fun1=NULL;
FUN2 fun2 = reinterpret_cast<FUN2>(fun1);
}
//补充1:函数指针
int sum(int a, int b)
{
return a + b;
}
typedef int (*FUNC1)(int, int);//声名函数指针
typedef int (FUNC2)(int, int);//声名函数指针
void _01Test05()
{
FUNC1 func1=sum;
FUNC2* func2 = sum;
//直接申明
void (*b[10])(void(*)());
void(*F)(void(*)());
F = NULL;
b[0] = F;
//通过typedef重命名声名
typedef void(*F1)();
typedef void(*Funb)(F1);
Funb bb[10];
bb[0] = F;
}
//补充2:回调函数
void mySum(int n)
{
if (n <= 0)
{
cout << "请输入一个正确的数" << endl;
return;
}
int sum=0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
cout << "从1到" << n << "之和为:" << sum << endl;
}
void callback_int(int n, void(*p)(int))
{
return p(n);
}
void _01Test06()
{
int n = 100;
callback_int(n, mySum);
}
void main()
{
//_01Test01();
//_01Test03();
_01Test06();
}
异常
示例:
#include<iostream>
using namespace std;
//异常基本语法
int divide(int x, int y)
{
if (y == 0)
{
throw y;//抛异常
}
return x / y;
}
void _02Test01()
{
//试着捕获异常
try
{
divide(10, 0);
}
catch (int e)//异常时根据抛出的类型来匹配
{
cout << "除数为" << e << "!" << endl;
}
}
void main()
{
_02Test01();
}
栈解旋
概念:
- 异常被抛出后,从进入try块起,到异常被抛出前,这器件在栈上的所有对象,都会别被自动析构,析构的顺序和构造顺序相反,这一过程称之为栈的解旋。
示例:
#include<iostream>
using namespace std;
//栈解旋
class Person
{
public:
Person()
{
cout << "构造函数调用" << endl;
}
~Person()
{
cout<< "析构函数调用" << endl;
}
};
int myDivide(int a, int b)
{
Person p1, p2;
if (b == 0)
{
throw b;
}
return a / b;
}
void _03Test01()
{
try
{
myDivide(10, 0);
}
catch (int w)
{
cout << "捕获异常" << endl;
}
}
void main()
{
_03Test01();
//先析构后捕获异常
}
异常接口说明
#include<iostream>
using namespace std;
//异常接口说明
//只能抛出int, float, char三种类型的异常
void func1() throw(int, char, float)
{
throw "abc";//报错 异常未处理
}
//不能抛出任何异常
void func2() throw()
{
throw -1;
}
//可以抛出任何异常
void func3()
{
}
void _04Test01()
{
try
{
func1();
func2();
}
catch (char *c)
{
cout << c << endl;
}
catch (int e)
{
cout << e;
}
catch (...)//抛出所有异常
{
cout << "异常类型不确定" << endl;
}
}
void main()
{
_04Test01();
}
自定义异常和生命周期
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//自定义异常类型
class MyException
{
public:
char* m_Error;
public:
MyException(const char* str)
{
cout << "构造函数的调用" << endl;
this->m_Error = new char[strlen(str) + 1];
strcpy(this->m_Error, str);
}
MyException(const MyException& e)
{
cout << "拷贝构造函数的调用" << endl;
this->m_Error = new char[strlen(e.m_Error) + 1];
strcpy(this->m_Error, e.m_Error);
}
MyException& operator=(const MyException& e)
{
cout << "赋值构造函数的调用" << endl;
if (this != NULL)
{
delete this;
}
this->m_Error = new char[strlen(e.m_Error) + 1];
strcpy(this->m_Error, e.m_Error);
return *this;
}
~MyException()
{
cout << "析构函数的调用" << endl;
if (this->m_Error != NULL)
{
delete this->m_Error;
}
}
void what()
{
cout << this->m_Error << endl;
}
};
void fun1()
{
throw MyException("自定义异常");
}
void fun2()
{
throw new MyException("自定义异常");
}
void _05Test01()
{
//1、捕获异常对象 通过拷贝构造函数调用 将异常复制一份给e
try
{
fun1();
}
catch (MyException e)
{
e.what();
}
//2、捕获异常对象引用 只会执行一次构造函数和析构函数
cout << "---------------------------" << endl;
try
{
fun1();
}
catch (MyException &e)
{
e.what();
}
//3、捕获异常对象的指针 需要new一个MyException 并手动释放
cout << "---------------------------" << endl;
try
{
fun2();
}
catch (MyException* e)
{
e->what();
delete e;
}
}
void main()
{
_05Test01();
}
绑定适配器
功能:
- 将二元函数对象转变为一元函数对象
bind1st
- 将参数绑定为函数对象的第一个参数(这里的参数指的是额外参数,而不是容器中的元素)
bind2nd
- 将参数绑定为函数对象的第二个参数
示例:
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
//绑定适配器
//bind1st - 将参数绑定为函数对象的第一个参数(这里的参数指的是额外参数,而不是容器中的元素)
//bind2nd - 将参数绑定为函数对象的第二个参数
class MyPrint:public binary_function<int,int,void>
{
public:
void operator()(int num1,int num2) const
{
cout << "num1=" << num1 << " num2=" << num2 <<" 结果为:" <<num1+num2<< endl;
}
};
void _03Test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), bind1st( MyPrint(),100));
cout << "--------------------------------" << endl;
for_each(v.begin(), v.end(), bind2nd( MyPrint(),100));
}
void main()
{
_03Test01();
}
取反适配器
功能:
- 将谓词进行取反操作
not1: 对一元谓词取反
not2: 对二元谓词取反
示例:
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
//取反适配器
//not1:对一元谓词取反
//not2:对二元谓词取反
class MyPrint
{
public:
void operator()(int num)
{
cout << num << " ";
}
};
//1、not1:对一元谓词取反
class MyGreater5 :public unary_function<int, bool>
{
public:
bool operator()(int num)const
{
return num > 5;
}
};
void _04Test01()
{
srand((unsigned int)time(NULL));
vector<int>v;
for (int i = 0; i < 10; i++)
{
int random = rand() % 10;
v.push_back(random);
}
vector<int>::iterator it1= find_if(v.begin(), v.end(), MyGreater5());
cout << *it1 << endl;
vector<int>::iterator it2 = find_if(v.begin(), v.end(),not1( MyGreater5()));
cout << *it2 << endl;
}
//2、not2:对二元谓词取反
class MyGreater :public binary_function<int, int, bool>
{
public:
bool operator()(int num1, int num2) const
{
return num1 > num2;
}
};
void _04Test02()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
int random = rand() % 100;
v.push_back(random);
}
sort(v.begin(), v.end(), MyGreater());
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
sort(v.begin(), v.end(), not2( MyGreater()));
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
}
void main()
{
//_04Test01();
_04Test02();
}
仿函数适配器
功能:
- 把普通函数转成函数对象
函数原型:
- ptr_fun(普通函数名);
示例:
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
//仿函数适配器
void myPrint(int num1,int num2)
{
cout << "num1=" << num1 << " num2=" << num2 << " 结果为:" << num1 + num2 << endl;
}
void _05Test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//ptr_fun(myPrint)将普通函数myPrint转化成一个函数对象
//再用bind2nd将myPring函数的第二个参数与100绑定
for_each(v.begin(), v.end(),bind2nd( ptr_fun(myPrint),100));
}
void main()
{
_05Test01();
}