使用异常抛出构造函数初始化对象的正确方法

rec*_*ion 5 c++ constructor exception

这似乎是一个微不足道的问题,但我现在已经挂了几个小时(可能是Java太多了我的C++ braincells).

我创建了一个具有以下构造函数的类(即没有默认构造函数)

VACaptureSource::VACaptureSource( std::string inputType, std::string inputLocation ) {
    if( type == "" || location == "" ) {
    throw std::invalid_argument("Empty type or location in VACaptureSource()");
}
type = inputType;
location = inputLocation;

// Open the given media source using the appropriate OpenCV function.
if( type.compare("image") ) {
    frame = cvLoadImage( location.c_str() );
    if( !frame ) {
        throw std::runtime_error("error opening file");
    }
}
else {
    throw std::invalid_argument("Unknown input type in VACaptureSource()");
}
Run Code Online (Sandbox Code Playgroud)

}

当我想创建一个实例时,我会使用

    // Create input data object
try {
    VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
}
catch( invalid_argument& ia ) {
    cerr << "FD Error: " << ia.what() << endl;
    usage(argv[0]);
}
catch( runtime_error& re ) {
    cerr << "FD Error: " << re.what() << endl;
    usage(argv[0]);
}
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,实例是此块的本地实例,我无法在其他任何地方引用它.另一方面,我不能说

VACAptureSource input;
Run Code Online (Sandbox Code Playgroud)

在程序的开头,因为没有默认的构造函数.

这样做的正确方法是什么?

谢谢!

jal*_*alf 11

为什么你需要在try街区之外引用它?

代替

try {
  VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
}
//catch....

//do stuff with input
Run Code Online (Sandbox Code Playgroud)

你可以把所有东西都移到try块中:

try {
  VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
  //do stuff with input
}
//catch....
Run Code Online (Sandbox Code Playgroud)

或者您可以将其分解为一个单独的函数,该函数从try块调用:

void doStuff(VACaptureSource& input){
  //do stuff with input
}

try {
  VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
  doStuff(input);
}
//catch....
Run Code Online (Sandbox Code Playgroud)

最后一个甚至为您提供了将构造与使用分离的好处,它可以很好地放入单元测试中,您可能希望函数在模拟对象上工作.


CAd*_*ker 8

使用指针(或其某些RAII版本)怎么样?

VACaptureSource* input = NULL;

try {
    input = new VACaptureSource(...);
} catch(...) {
    //error handling
}

//And, of course, at the end of the program
delete input;
Run Code Online (Sandbox Code Playgroud)

  • "邪恶"是一个非常强硬的词.但是,正如CAdaker所建议的那样,RAII(即自动破坏)变体,如std :: auto_ptr - 或任何适当的Boost自动指针 - 将是一个明智的选择. (3认同)
  • 这看起来很傻.当正常变量起作用时,为什么要使用指针!!!! (3认同)