一、异常的概念
概念:函数的设计者检查错误,并抛出异常,函数的使用者来捕获异常,处理异常
二、标准异常(if throw ; try catch(const invalid_argument & xxx){cout<<xxx.what()})
int divide(int x,int y){
if (y == 0){
throw("y==0!!!!!");
}
else
return x/y;
}
int main(){
try{
cout<<divide(5,0)<<endl;
}catch(const invalid_argument & errmsg){
cout<<errmsg.what()<<endl;
}
return 0;
}
三、自定义异常(由标准异常派生)
class Myexception: public exception{
public:
Myexception(const char *str) noexcept : ptr(str){
}
~Myexception ()noexcept{
}
public:
const char *what() const noexcept{ //重写基类的虚函数
return ptr; //throw("xxxxxxxx"); 后续的错误语句就是这里的ptr
}
private:
const char *ptr;
};
int divior(int x,int y){
if (y!=0 && x!=0)
return x/y;
else if(x == 0)
throw Myexception("x == 0!!"); //自定义派生异常
else
throw invalid_argument("y == 0!!"); //标准异常
}
int main(){
try{
cout<<devior(0,0)<<endl;
}catch(invalid_argument &xxxx){
cout<<xxxx.what()<<endl;
}catch(const Myexcepyion &xxxx){
cout<<xxxx.what()<<endl;
}
return 0;
}
四、不由标准异常类派生,自定义异常类
class myexception{
public:
myexception(const char *str) noexcept: ptr(str) //指定异常不再抛异常
{
}
virtual ~myexception() noexcept //自动为序虚
{
}
virtual const char* what() const noexcept //重写基类的虚函数
{
return this->ptr;
}
private:
const char *ptr;
};
int divior(int x, int y)
throw(invalid_argument)//指定函数可以抛出invalid_argument类型的异常
{
if(y != 0)
return x/y;//正确:返回结果
else if(0 == x)
{
#if 0
throw myexception("x == 0");//抛出自定义异常
#else
myexception tmp("x == 0");
throw tmp;
#endif
}
else//y == 0
throw invalid_argument("invalid argument");//抛出标准异常
}
int main()
{
int m = 0;
int n = 1;
try{//检错
cout << divior(m,n) << endl;
}catch(const invalid_argument &iserr)//捕获异常
{
cout << iserr.what() << endl;//打印异常原因 处理异常
}catch(const myexception &iserr)//捕获异常
{
cout << iserr.what() << endl;//打印异常原因 处理异常
}
return 0;
}
五、转换函数
1.explicit关键字:阻止隐式类型转换(小的赋给大的,也叫小转大)
class Demo{
public:
explicit Demo(int val) //explict:阻止隐式类型转换
{
this->val = val;
cout << __func__ << ":" << __LINE__ << endl;
}
};
int main()
{
Demo obj(666);
obj = 123;//Demo tmp(123); obj = tmp; 隐式类型转换: int -> Demo
cout << obj.getval() << endl;
return 0;
}
2.C++标准转换函数
编译时转换:reinterpret_cast、const_cast、static_cast
运行时候转换:dynamic_cast
2.1 1)reinterpret_cast
语法:reinterpret_cast<new type>(expression)
功能:将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型
eg:
char *p;
int *q;
q = reinterpret_cast<int *> (p);//char * -> int *
2.2 2)const_cast
语法:const_cast< new type>( expression)
功能:const指针与普通指针间的相互转换,注意:不能将非常量指针变量转换为普通变量
eg:
const int *p;
int *q;
q = const_cast<int *>(p);//const int * -> int *
2.3 3)static_cast(普通类类型转换) 常用
语法:static_cast<new type>(expression)
功能:主要用于基本类型间的相互转换,和具有继承关系间的类型转换
eg:
class Base{
public:
Base()
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Base()
{
cout << __func__ << ":" << __LINE__ << endl;
}
};
class Inherit : public Base{
public:
Inherit()
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Inherit()
{
cout << __func__ << ":" << __LINE__ << endl;
}
};
int main()
{
Base *p;
Inherit *q;
//p = q;//Inherit * -> Base *
q = static_cast<Inherit *> (p); //Base * -> Inherit *
return 0;
}
2.4 dynamic_cast(有虚函数的类型转换)
语法:dynamic_cast<newtype>(expression)
功能:只有类中含有虚函数才能用dynamic_cast;仅能在继承类对象间转换
注意:dynamic_cast具有类型检查的功能,比static_cast更安全
eg:
class Base{
public:
Base()
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Base()
{
cout << __func__ << ":" << __LINE__ << endl;
}
};
class Inherit : public Base{
public:
Inherit()
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Inherit()
{
cout << __func__ << ":" << __LINE__ << endl;
}
};
int main()
{
Base *p;
Inherit *q;
//p = q;//Inherit * -> Base *
q = dynamic_cast<Inherit *> (p); //Base * -> Inherit *
return 0;
}
2.5 自定义转换函数
eg:
class Demo{
public:
explicit Demo(int val) : val(val)
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Demo()
{
cout << __func__ << ":" << __LINE__ << endl;
}
public:
operator int() const //转换函数:Demo -> int
{
cout << __func__ << ":" << __LINE__ << endl;
return this->val;
}
private:
int val;
};
int main()
{
Demo obj(666);
int i;
i = obj; //Demo -> int
cout << "i=" << i << endl;
return 0;
}
六、智能指针
本质:类模板,模板中重载了->和*运算符(取内容)
解决:只malloc,而不去关心free
1. shard_ptr
template <class T>
class myshared_ptr{
public:
myshared_ptr(T *p) : ptr(p)
{
count ++;
}
myshared_ptr(const myshared_ptr<T> &obj)
{
count ++;
}
~myshared_ptr()
{
count--;
if(0 == count)
delete ptr;
}
public:
operator ->()//重载->运算符
{
}
operator *() //重载*运算符
{
}
private:
T *ptr;
};
int main(){
shared_ptr<Demo> p(new Demo);
shared_ptr<Demo> pp = p;
return 0;
}
2.unique_ptr指针(独享指针)
class Demo{
public:
explicit Demo(int val=0) :val(val)
{
cout << __func__ << ":" << __LINE__ << endl;
}
virtual ~Demo()
{
cout << __func__ << ":" << __LINE__ << endl;
}
public:
void setval(int val)
{
this->val = val;
}
int getval() const
{
return this->val;
}
private:
int val;
};
int main()
{
unique_ptr<Demo> p(new Demo);//构造对象p
//unique_ptr<Demo> pp = p;//禁止拷贝构造
p->setval(666);//等价:(*p).setval(666);
cout << p->getval() << endl;
return 0;
}
3.weak_ptr(弱指针)
通常配合共享指针进行操作;
int main()
{
shared ptr<Demo> p(new Demo);//构造对象p
weak_ptr<Demo> pp = p;//pp和p都指向Demo
p.reset();//delete Demo
if (pp.expired())
cout<<"obj is not exist"<<endl;
}
七、STL模板库(了解程度有待提高)
STL的六个部分:容器 迭代器 算法 空间配置器 配接器 仿函数
STL序列容器:vector -- 动态数组 deque -- double-ended queue数组的头尾增删很快
list -- 双向链表
//vector向量
相当于数组
eg:
int main()
{
int i = 0;
list<int> a;//构造链表对象
cout << a.size() << endl;
for(i=0;i<5;i++) //头部插入节点
a.push_front(i+1);
for(i=0;i<5;i++)
a.push_back(i+1);
list<int>::const_iterator start = a.cbegin();//迭代器 获取第一个节点的指针
for(i=0;i<a.size();i++)//遍历链表节点
{
cout << *start << " ";
start++;
}
cout << endl;
return 0;
}