在构造函数中初始化成员有错误

时间:2016-08-09 20:22:13

标签: c++

我是C ++的新手所以请耐心等待。

当没有有效值分配给成员时,是否有最佳实践来初始化构造函数中的成员?

例如:

device_123::device_123(data_struct_t * initData)  
{
    if(initData==NULL)
    {
       print_error(0);
       // what to initialize foo/bar to?
    }
    else
    {
      foo = initData->foo;
      bar = initData->bar; 
    }
}

在“initData == NULL”的情况下,有没有一种简洁的方法来初始化foo&酒吧说:“嘿,我们实际上并没有为我们分配正确的价值”。

我知道这个问题可能听起来特定于我的代码实现应如何解释foo / bar,但我只是想知道是否有最佳实践。

3 个答案:

答案 0 :(得分:5)

如果您想确保您的类构造函数只接受有效指针,请更改签名以使用引用:

class defice_123 {
public:
  defice_123(data_struct_t& initData) : foo(initData.foo), boo(initData.boo) {
  }
...
};

答案 1 :(得分:2)

如上所述,您可以在构造函数中强制执行签名。

还有其他选择:

  1. 当构造函数出错时,抛出异常
  2. 在构造函数中做最少的事情(零变量)并将复杂的东西移动到初始化函数,您可以灵活地在失败时返回更多细节。

答案 2 :(得分:0)

我们在这里谈论最佳做法,所以我要采取强硬立场。总有例外,但例外是例外,而不是最佳实践。

最佳做法是说,在获得初始化对象所需的信息之前,不要分配对象。这是作为Resource Allocation Is Initialization或RAII的一部分捆绑在一起的。

使用RAII,当你构造一个对象时,它必须从构造函数中完整,有效并且可以使用。如果对象不能被完全和正确地初始化,则应该对其进行废弃,丢弃,删除或以其他方式处置,以便绝对不会混淆对象的状态。该对象要么好又可以使用或不存在。

如果没有足够的信息使对象有效,则过早地实例化对象。如果在构造对象时输入使得对象无法有效,则清理,抛出异常并返回对象。创建者没有获得无效对象。如初。

RAII使您无需在使用对象之前不断检查object.isvalid()之类的内容。你有一个对象,它是一个好对象。如果对象包装资源,则该资源可用并在您需要的时候可访问。您不必担心打开一个不存在的文件等微不足道的错误。如果您有一个对象,则该文件已打开并可供访问。

作为额外的奖励,当正确观察到RAII时,保证在对象超出范围时释放资源。静态分配(通常是堆栈)和Smart pointers are your friend

这需要相当成熟的异常使用,因为您不会获得返回的错误代码,因此抛出的异常需要对错误类型有意义或包含信息性what字符串并得到有效处理。在构造之前可能需要捕获由于例程事件导致的失败,以避免在性能至关重要时在异常处理程序中浪费时间。