2016-08-09 86 views
1

我是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,但我只是想知道是否有最佳做法。

+1

如果您必须初始化'foo'和'bar'数据成员,那么为什么没有一个构造函数来决定这个要求呢?例如,'device_123 :: device_123(const Foo&f,const Bar&b):foo(f),bar(b){}'。 –

+0

“foo”和“bar”的“未真正初始化”值是什么? –

回答

5

如果你想确保你的类的构造函数只需要有效的指针,更改签名使用参考:

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

正如上面回答您可以在构造函数中执行的签名。

也有备选方案:

  1. 出问题的时候在构造函数中,抛出异常
  2. 做的最起码的事情在构造函数(零个变量)和复杂的东西搬到一个初始化函数,你有灵活性在失败时返回更多细节。
0

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

最佳实践说,除非您有需要初始化对象的信息,否则不要分配对象。这是作为Resource Allocation Is Initialization或RAII的一部分捆绑在一起的。

随着RAII,当你构造一个对象时,它必须从构造函数中出来,完成,有效并且可以使用。如果一个对象不能被完全和正确地初始化,它应该被废弃,丢弃,消除或以其他方式处理,以便对对象的状态绝对没有混淆。该对象不是好的,可以使用或不存在。

如果您没有足够的信息来使对象有效,那么您实例化的对象太早。如果在构造对象的时候输入是无效的,那么你需要清理,抛出一个异常,然后将对象返回给它。创建者不会收到无效的对象。永远。

在使用对象之前,RAII可以帮助您不断检查诸如object.isvalid()之类的内容。你有一个对象,这是一个很好的对象。如果对象包装资源,则该资源在您需要它的瞬间即可用并可访问。您不必担心打开不存在的文件等琐碎的错误。如果您有对象,则该文件已打开并准备好进行访问。

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

这需要相当成熟的异常使用,因为您不会得到返回的错误代码,所以抛出的异常需要对错误类型有意义或者包含信息性的字符串并进行有效处理。如果性能非常关键,可能需要在构建之前捕获由于例程事件而导致的故障,以避免在异常处理程序中浪费时间。

相关问题