zoukankan      html  css  js  c++  java
  • 构造函数和析构函数中得异常处理

    构造函数和析构函数中得异常处理

    一. 构造函数

    总结如下:

    1. 构造函数中抛出异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。

    2. 因为析构函数不能被调用,所以可能会造成内存泄露或系统资源未被释放。

    3. 构造函数中可以抛出异常,但必须保证在构造函数抛出异常之前,把系统资源释放掉,防止内存泄露。(如何保证???使用auto_ptr???)

    试验代码:

    复制代码
     1 //ExceptionConstructor.h
     2 #pragma once
     3 #include <stdexcept>
     4 
     5 class CExceptionConstructor
     6 {
     7 public:
     8     CExceptionConstructor();
     9     ~CExceptionConstructor();
    10 };
    11 
    12 class CExceptionAlpha
    13 {
    14 public:
    15     explicit CExceptionAlpha(int age) throw(std::invalid_argument);
    16     ~CExceptionAlpha();
    17 
    18 private:
    19     int m_Age;
    20 };
    21 
    22 class CExceptionBeta
    23 {
    24 public:
    25     explicit CExceptionBeta(int height) throw(std::invalid_argument);
    26     ~CExceptionBeta();
    27 
    28 private:
    29     int m_Height;
    30 };
    31 
    32 class CExceptionGroup
    33 {
    34 public:
    35     explicit CExceptionGroup(int count) throw(std::invalid_argument);
    36     ~CExceptionGroup();
    37 
    38 private:
    39     CExceptionAlpha m_Alpha;
    40     CExceptionBeta m_Beta;
    41     int m_Count;
    42 };
    复制代码
    复制代码
     1 //ExceptionConstructor.cpp
     2 #include "ExceptionConstructor.h"
     3 
     4 CExceptionConstructor::CExceptionConstructor()
     5 {
     6 }
     7 
     8 
     9 CExceptionConstructor::~CExceptionConstructor()
    10 {
    11 }
    12 
    13 CExceptionAlpha::CExceptionAlpha(int age)
    14 {
    15     if (age < 0 || age > 200)
    16         throw std::invalid_argument("Alpha invalid argument");
    17     m_Age = age;
    18     printf("CExceptionAlpha construct!
    ");
    19 }
    20 
    21 
    22 CExceptionAlpha::~CExceptionAlpha()
    23 {
    24     printf("CExceptionAlpha desconstruct!
    ");
    25 }
    26 
    27 CExceptionBeta::CExceptionBeta(int height)
    28 {
    29     if (height < 5 || height > 500)
    30         throw std::invalid_argument("Beta invalid argument");
    31     m_Height = height;
    32     printf("CExceptionBeta construct!
    ");
    33 }
    34 
    35 
    36 CExceptionBeta::~CExceptionBeta()
    37 {
    38     printf("CExceptionBeta desconstruct!
    ");
    39 }
    40 
    41 CExceptionGroup::CExceptionGroup(int count):
    42     m_Alpha(10), m_Beta(20)
    43 {
    44     if (count < 0 || count > 500)
    45         throw std::invalid_argument("Group invalid argument");
    46     m_Count = count;
    47     printf("CExceptionGroup construct!
    ");
    48 }
    49 
    50 
    51 CExceptionGroup::~CExceptionGroup()
    52 {
    53     printf("CExceptionGroup desconstruct!
    ");
    54 }
    复制代码
    复制代码
     1 // cpp_toys.cpp : Defines the entry point for the console application.
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "ExceptionConstructor.h"
     6 
     7 int main()
     8 {
     9     try
    10     {
    11         //CExceptionAlpha construct!
    12         //CExceptionBeta construct!
    13         //CExceptionBeta desconstruct!
    14         //CExceptionAlpha desconstruct!
    15         //Error occur Beta invalid argument
    16         CExceptionGroup group(-1);
    17 
    18         /*CExceptionAlpha construct!
    19         CExceptionBeta construct!
    20         CExceptionGroup construct!
    21         CExceptionGroup desconstruct!
    22         CExceptionBeta desconstruct!
    23         CExceptionAlpha desconstruct!*/
    24         CExceptionGroup group(20);
    25     }
    26     catch(std::invalid_argument &ex)
    27     {
    28         printf("Error occur %s
    ", ex.what());
    29     }
    30     
    31     return 0;
    32 }
    复制代码


    二. 析构函数

    参照《Effective C++》中条款08:别让异常逃离析构函数。

      总结如下:

    1. 不要在析构函数中抛出异常!虽然C++并不禁止析构函数抛出异常,但这样会导致程序过早结束或出现不明确的行为。

    2. 如果某个操作可能会抛出异常,class应提供一个普通函数(而非析构函数),来执行该操作。目的是给客户一个处理错误的机会。

    3. 如果析构函数中异常非抛不可,那就用try catch来将异常吞下,但这样方法并不好,我们提倡有错早些报出来。

    本文参考:

    1. 《Effective C++》条款08:别让异常逃离析构函数。

    2. C++构造函数中抛出的异常

    http://blog.csdn.net/deyili/article/details/6332760

    3. C++ 构造函数抛出异常会引起内存泄漏吗?:

    http://blog.csdn.net/sxf_824/article/details/4926687

    4. 构造函数中可不可以抛出异常?析构函数呢?

    http://blog.csdn.net/panlong1987/article/details/1835454
    5. 是否能在构造函数,析构函数中抛出异常?
    http://www.cnblogs.com/KevinSong/p/3323372.html

    诸位正值青春年少,一定恣情放纵,贪恋香艳梅施之情,喜欢风流雅韵之事,洒脱木拘。然而诸位可知,草上露一碰即落,竹上霜一触即溶,此种风情难于长久。
  • 相关阅读:
    uniapp、小程序之swiperitem内容过多显示不全的解决方案
    PingFang(苹方)字体的引用
    Vue项目中使用websocket
    uniapp页面跳转传递参数过长
    uniapp开发的h5,使用微信授权登录(前置条件+具体代码)
    Maven工具安装使用
    Lombok代码生成插件使用
    对不起,我的文章暂时无法公开!
    [iOS]学习笔记7(CATransform3DFlip效果)
    [iOS]学习笔记8 (iOS之阻塞)
  • 原文地址:https://www.cnblogs.com/shilipojianshen/p/13558338.html
Copyright © 2011-2022 走看看