【发布时间】:2017-12-04 19:58:18
【问题描述】:
当构造函数抛出异常时,如何防止对象被创建?
在下面的示例中,我创建了一个 Month() 类,其 int month_ 属性的合法值在 1 到 12 的范围内。我实例化了 December,或 dec,其整数值为 13。应该会抛出异常,但对象仍在创建中。然后调用析构函数。
如何在抛出异常时中止创建类实例?
输出
-- Month() constructor called for value: 2
-- Month() constructor called for value: 6
-- Month() constructor called for value: 13
EXCEPTION: Month out of range
2
6
13
-- ~Month() destructor called.
-- ~Month() destructor called.
-- ~Month() destructor called.
Press any key to exit
最小、完整且可验证的示例
#include <iostream>
#include <string>
class Month {
public:
Month(int month) {
std::cout << "-- Month() constructor called for value: " << month << std::endl;
try {
// if ((month < 0) || month > 12) throw 100; Good eye, Nat!
if ((month < 1) || month > 12) throw 100;
} catch(int e) {
if (e == 100) std::cout << "EXCEPTION: Month out of range" << std::endl;
}
month_ = month;
}
~Month() {
std::cout << "-- ~Month() destructor called." << std::endl;
}
int getMonth()const { return month_; }
private:
int month_;
};
int makeMonths() {
Month feb(2), jun(6), dec(13);
std::cout << feb.getMonth() << std::endl;
std::cout << jun.getMonth() << std::endl;
std::cout << dec.getMonth() << std::endl;
return 0;
}
int main() {
makeMonths();
std::cout << "Press any key to exit"; std::cin.get();
return 0;
}
【问题讨论】:
-
不要捕获异常。让它从构造函数中抛出。
-
if ((month < 0) || month > 12)允许 13 个有效值,0到12。假设您使用的是零索引,那么if (month < 0 || month >= 12)可能是要走的路。或者,如果您想要传统的序数索引,if (month <= 0 || month > 12)。 -
好眼纳特!!!!
标签: c++ c++11 constructor exception-handling try-catch