Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to initialize an object with exception throwing constructor

This seems to be a trivial question but I got hung on it for a few hours now (maybe too much Java killed my C++ braincells).

I have created a class that has the following constructor (i.e. no default constructor)

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()");
}

}

When I want to create an instance, I use

    // 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]);
}

However, in this case the instance is local to this block and I can't refer to it anywhere else. On the other hand, I can't say

VACAptureSource input;

at the beginning of the program since there's no default constructor.

What is the correct way to do this?

Thanks!

like image 215
recipriversexclusion Avatar asked Jun 30 '09 15:06

recipriversexclusion


People also ask

How do you initialize an object in a constructor?

There are two ways to initialize a class object: Using a parenthesized expression list. The compiler calls the constructor of the class using this list as the constructor's argument list. Using a single initialization value and the = operator.

How do you handle an exception that is thrown from the constructor?

When throwing an exception in a constructor, the memory for the object itself has already been allocated by the time the constructor is called. So, the compiler will automatically deallocate the memory occupied by the object after the exception is thrown.

Should a constructor throw an exception?

The short answer to the question “can a constructor throw an exception in Java” is yes! Of course, properly implementing exceptions in your constructors is essential to getting the best results and optimizing your code.

What happens when constructor throws exception?

Throw an Exception from a ConstructorThe object remains in a partially initialized state until it gets garbage collected.so we conclude that saving a reference to the object from the constructor itself (by using this reference) is a risky thing, since we may give access to an object in an invalid state.


1 Answers

why do you need to refer to it outside the try block?

Instead of

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

//do stuff with input

you could move everything into the try block:

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

or you could factor it out into a separate function, which is called from the try block:

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....

The last one even gives you the nice bonus of separating the construction from use, which places nicely into unit tests where you might want the function to work on a mock object instead.

like image 193
jalf Avatar answered Oct 11 '22 22:10

jalf