And*_*ndy 23 c++ error-handling constructor return-value
请注意,这是一个关于构造函数的问题,而不是关于处理时间的类.
假设我有一个这样的类:
class Time
{
protected:
    unsigned int m_hour;
    unsigned int m_minute;
    unsigned int m_second;
public:
    Time(unsigned int hour, unsigned int minute, unsigned int second);
};
Run Code Online (Sandbox Code Playgroud)
虽然我希望成功构建一个,但我希望b的构造函数失败.
Time a = Time(12,34,56);
Time b = Time(12,34,65); // second is larger than 60
Run Code Online (Sandbox Code Playgroud)
但是,这是不可能的,因为构造函数不返回任何值,并且总是会成功.
构造函数如何告诉程序它不满意?我想到了几个方法:
哪种方法在工业中最常见?或者有什么我可能错过的?
sha*_*oth 38
典型的解决方案是抛出异常.
其背后的逻辑如下:构造函数是一种将一块内存转换为有效对象的方法.它成功(正常完成)并且你有一个有效的对象,或者你需要一些不可忽视的问题指标.例外是使问题在C++中不可忽略的唯一方法.
Éri*_*ant 31
另一种选择,为了完整性:
例如,在"时间"课程中,您可以:
class Time{
public:
    Time(Hours h, Minutes m, Seconds s);
//...
};
Run Code Online (Sandbox Code Playgroud)
小时,分钟和秒是有界值.例如,使用(尚未)Boost Constrained Value库:
typedef bounded_int<unsigned int, 0, 23>::type Hours;
typedef bounded_int<unsigned int, 0, 59>::type Minutes;
typedef bounded_int<unsigned int, 0, 59>::type Seconds;
Run Code Online (Sandbox Code Playgroud)
        Ste*_*sop 12
通常我会说(1).但是如果你发现调用者都在使用try/catch包围构造,那么你也可以在(3)中提供静态辅助函数,因为通过一些准备工作,异常就不可能实现.
还有另一种选择,虽然它对编码风格有重大影响所以不应轻易采用,
5)不要将参数传递给构造函数:
class Time
{
protected:
    unsigned int m_hour;
    unsigned int m_minute;
    unsigned int m_second;
public:
    Time() : m_hour(0), m_minute(0), m_second(0) {}
    // either return success/failure, or return void but throw on error,
    // depending on why the exception in constructor was undesirable.
    bool Set(unsigned int hour, unsigned int minute, unsigned int second);
};
Run Code Online (Sandbox Code Playgroud)
它被称为两阶段构造,并且精确地用于构造函数不希望或不可能抛出异常的情况.使用nothrow new编译的代码-fno-exceptions可能是经典案例.一旦你习惯了它,它就会比你最初想的那样烦人.
Tim*_*mbo 11
还有一种可能的方式.我并不是说这是首选,只是为了完整性而添加它:
创建一个工厂函数,在堆上创建类的实例,如果创建失败则返回空指针.
对于类似于类型的对象而言,这不适合作为日期,但可能有一些有用的应用程序.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           9256 次  |  
        
|   最近记录:  |