首页 / 技术类 / C++ / 道德问题?论new操作失败后的操作

[20100330道德问题?论new操作失败后的操作

2010-03-30 22:31:00

先看一个例子。首先,我要写一个vector;其次,为了使用方便,我需要提供一个带 size 参数的构造函数。要求就这两点。

那么,势必要:

 1class vector
 2{
 3public:
 4    vector(size_t size)
 5    {
 6        // ...
 7        m_pData = new int[size]; // 假设就是 int 这样的基本类型好了,以避免下面可能出现的离题
 8        // ...
 9    }
10};

问题来了。new 不是有可能失败吗?失败了在老编译器里会返回 NULL(这个情形也先无视),在新编译器里会抛异常。那么,在这里要不要进行检查呢?如果检查:

1try
2{
3    m_pData = new int[size];
4}
5catch (...)
6{
7
8}

catch到了。那么在这里可以干啥呢?似乎。。。啥也干不了!作为构造函数,没法使用返回值,自然只能使用异常来提示外界;既然本来就是异常,我又何必在这里 try 一次呢?(假设这里没有其他错误要处理,也假设这里的类型是int之类的基本类型,不会出现执行元素的构造函数失败的情形)

既然这里的 try 让我们如此无奈,那么就不必 try 了。这个时候,我需要给 vector(size_t size) 标记上 throw 吗?如果不标记,使用者怎么知道这里可能会有异常?如果标记了,或者没标记但使用者意识到了,那么他会这样用:

 1try
 2{
 3    vector v(10);
 4    // Task with v
 5    // ...
 6    // ...
 7    // ...
 8}
 9catch (...)
10{
11    // Error handler
12}

因为 v 的作用域被限制在了 try 内,所以所有的与 v 相关的逻辑代码全部要放在 try 内部了。这种样子似乎与 C# 很像!在 C# 里,try...catch... 是标准的做法;但是在 C++ 里,似乎不会如此经常地用 try catch,要不然,为什么我见过的 C++ 代码都不是这样子的呢?两年前在金山实习的时候,有一次我把 try...catch 当做通用的错误处理来做,所有的错误都搞成一种异常,返回值仅返回正常值。结果董波叔叔说,这样子是不对滴,但是没给出让我信服理由,可能就是,C++ 的 try...catch 的性能很不好之类的。(C# 以及 Java 的 try...catch 的性能好吗?)

好,既然大家都不这么办,是不是这里也不用 try 了?于是,内存分配错误就让它自生自灭了……记得以前某本书上看到,说这种情形下的处理,仅仅是一个道德问题而已。真的无解吗?

如果放宽要求,不要求在构造函数提供内存分配,那倒是有一种解法——分两阶段构造:

 1class vector
 2{
 3public:
 4    vector()
 5    {
 6        // ...
 7    }
 8    bool allocate(size_t size)
 9    {
10        try
11        {
12            m_pData = new int[size];
13        }
14        catch (...)
15        {
16            return false;
17        }
18        if (m_pData == NULL)
19        {
20            return false;
21        }
22        // Other code ...
23        return true;
24    }
25};

但是使用起来就不“方便”了。现实中,这种情形倒是存在,如 CWindowCreate,还有啥啥啥的 Init 等等。

真的没有办法兼顾方便与安全吗?


首发:http://www.cppblog.com/Streamlet/archive/2010/03/30/111058.html



NoteIsSite/0.4