C++异常 智能指针类型转换

异常

1.当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的直接或间接的调用者处理这个错误。

2.异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。

3.被选中的处理代码是调用链中与该对象类型匹配且离抛出异常最近的那一个。

4.try catch会带与其未曾料到的栈溢出。

5.C++异常处理机制是一个用来有效地处理运行错误的非常强大且灵活的工具,主要使用了三个关键字:try,catch,throw。抛出异常即检测是否产生异常。try catch不分家,throw出的错误,可以在catch中捕获,进行对应的处理,一般来说throw出的变量的类型,和catch的类型必须完全匹配,只有一种特例:子类的对象可以被父类的对象捕获。

6.在某个栈中抛出的错误可以由它的上一层栈进行处理。

智能指针

1.在有临时性对象的时候需要智能指针。智能指针是一种预防型的内存泄露的解决方案,智能指针在C++没有垃圾回收器环境下,可以很好地解决异常安全带来的内存泄漏问题。

2. 

#include
#include
#include
#include
#include
using namespace std;
template
class SmartPtr
{
public:
  SmartPtr(T* ptr=nullptr)
  :_ptr(ptr)
  {}
  ~SmartPtr()
  {
    if(_ptr)
     delete _ptr;
  }
private:
  T* _ptr;
};
void MergeSort(int* a,int n)
{
  int* tmp=(int*)malloc(sizeof(int)*n);
  SmartPtrsp(tmp);
  vectorv(1000000,0);
}
int main()
{
  try{
    int a[5]={4,5,3,2,1};
    MergeSort(a,5);
  }
  catch(const exception& e)
  {
    cout<

RAII:利用对象生命周期来控制程序资源(如内存,文件句柄,网络连接,互斥量)的简单技术。

在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。

有两大好处:

  1. 不需要显式地释放资源。
  2. 采用这种方式,对象所需的资源在其生命期内始终保持有效。

3.指针可以解引用,也可以通过->去访问所指空间中的内容。所以若想smartptr可以像指针一样使用,需要将*,->重载使用。

template
class SmartPtr
{
public:
  SmartPtr(T* ptr=nullptr)
  :_ptr(ptr)
  {}
  ~SmartPtr()
  {
    if(_ptr)
     delete _ptr;
  }
  T& operator*(){return *_ptr;}
  T* operator->(){return _ptr;}
private:
  T* _ptr;
};

4.auto_ptr:管理权转移的思想,会造成对象悬空。

5.unique_ptr:简单粗暴的防拷贝。

6.shared_ptr:通过引用计数的方式来实现多个shared_ptr对象之间共享资源:

  • shared_ptr在其内部,给每个资源都维护了一份计数,用来记录该份资源被几个对象共享。
  • 在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一。
  • 如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源。
  • 如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指针了。

当一个函数中出现大量的return,那么在每一次return前都要加入delete,这种操作非常麻烦且容易出错。智能指针是一个类模板,主要功能是假装自己是一个指针,通过析构函数解决资源释放问题。更加方便,安全的使用临时new出来的变量或对象。

三种指针在拷贝时的区别:

1.auto_ptr的拷贝是旧的给新的,旧的失效。

2.unique_ptr不允许创建新的。

3.shared_ptr随意拷贝。

weak_ptr特点:啥都没有,只能保存指针值。

删除器:构造的第二个参数可以传一个仿函数,代表析构的方式。

weak_ptr:解决循环引用的问题(智能指针指向的类型里,包含同样类型的智能指针(类似链表)在这种情况下,如果像链表那样赋值,就会产生循环引用问题)

 C++的类型转换

C语言类型转换:可视性比较差,难以跟踪错误的转换。

C++强制类型转换 :

1.static_cast:用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可以用static_cast,但它不能用于两个不相关的类型转换。不能用做一般指针间的转换。

2.reinterpret_cast:通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。对任意指针和数字进行转换。

3.const_cast:最常用的用途就是删除变量的const属性,方便赋值,指针引用均可操作,去掉或加上const属性。

4.dynamic_cast:用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)。

  • dynamic_cast只能用于含有虚函数的类,必是多态类
  • dynamic_cast会先检查是否能转换成共,能成功则转换,不能返回0

强制类型转换关闭或挂起了正常的类型检查,应尽量避免使用强制类型转换。

explicit关键字阻止经过转换构造函数进行的隐式转换的发生。

总结:

1.RTTI Run-time Type identification 运行时类型识别。

  • typeid:可以判断变量的类型,可以判断两个变量的类型是否相同,可以打印变量的类型。

2.强制转换.

  • static_cast:静态类型间的转换,包括数字,父子类指针间的转换。
  • reinterpret_cast:可以在指针和整型间任意互相转化。
  • const_cast:给一个指针或引用加上或去掉const属性。
  • dynamic_cast:利用RTTI技术进行识别的父子类指针间转化,会阻止原生的父类指针转换为子类指针,阻止的方式是扔出一个bad_cast异常,且表达式的值变为NULL。

你可能感兴趣的:(c++学习概括总结)