您的位置:首页 > 其它

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

2016-01-10 21:46 218 查看
一. 构造函数

总结如下:

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

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

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

试验代码:

//ExceptionConstructor.h
#pragma once
#include <stdexcept>

class CExceptionConstructor
{
public:
CExceptionConstructor();
~CExceptionConstructor();
};

class CExceptionAlpha
{
public:
explicit CExceptionAlpha(int age) throw(std::invalid_argument);
~CExceptionAlpha();

private:
int m_Age;
};

class CExceptionBeta
{
public:
explicit CExceptionBeta(int height) throw(std::invalid_argument);
~CExceptionBeta();

private:
int m_Height;
};

class CExceptionGroup
{
public:
explicit CExceptionGroup(int count) throw(std::invalid_argument);
~CExceptionGroup();

private:
CExceptionAlpha m_Alpha;
CExceptionBeta m_Beta;
int m_Count;
};


//ExceptionConstructor.cpp
#include "ExceptionConstructor.h"

CExceptionConstructor::CExceptionConstructor()
{
}

CExceptionConstructor::~CExceptionConstructor()
{
}

CExceptionAlpha::CExceptionAlpha(int age)
{
if (age < 0 || age > 200)
throw std::invalid_argument("Alpha invalid argument");
m_Age = age;
printf("CExceptionAlpha construct!\n");
}

CExceptionAlpha::~CExceptionAlpha()
{
printf("CExceptionAlpha desconstruct!\n");
}

CExceptionBeta::CExceptionBeta(int height)
{
if (height < 5 || height > 500)
throw std::invalid_argument("Beta invalid argument");
m_Height = height;
printf("CExceptionBeta construct!\n");
}

CExceptionBeta::~CExceptionBeta()
{
printf("CExceptionBeta desconstruct!\n");
}

CExceptionGroup::CExceptionGroup(int count):
m_Alpha(10), m_Beta(20)
{
if (count < 0 || count > 500)
throw std::invalid_argument("Group invalid argument");
m_Count = count;
printf("CExceptionGroup construct!\n");
}

CExceptionGroup::~CExceptionGroup()
{
printf("CExceptionGroup desconstruct!\n");
}


// cpp_toys.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ExceptionConstructor.h"

int main()
{
try
{
//CExceptionAlpha construct!
//CExceptionBeta construct!
//CExceptionBeta desconstruct!
//CExceptionAlpha desconstruct!
//Error occur Beta invalid argument
CExceptionGroup group(-1);

/*CExceptionAlpha construct!
CExceptionBeta construct!
CExceptionGroup construct!
CExceptionGroup desconstruct!
CExceptionBeta desconstruct!
CExceptionAlpha desconstruct!*/
CExceptionGroup group(20);
}
catch(std::invalid_argument &ex)
{
printf("Error occur %s\n", ex.what());
}

return 0;
}


二. 析构函数

参照《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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: