Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'m writing a C++ wrapper for my C library (my C++ skills are a bit rusty) and

ID: 654312 • Letter: I

Question

I'm writing a C++ wrapper for my C library (my C++ skills are a bit rusty) and I'm wondering what's preferable: allowing user to construct objects themselves or give them objects via getters?

What would be idiomatic C++ equivalent of that C function?

result* process_foo(library_handle*, foo*);
a constructor like this:

Result *res = new Result(library_handle, foo);
or a getter like this? (that basically wraps the above code):

Result *res = library->get_result(foo);
Does the answer change if creation of the result could fail?

Getter could return NULL, but what should constructor version do on failure? AFAIK some people don't like exceptions. An extra method such as init() or is_valid() doesn't seem elegant.

OTOH the Result object sticks to RAII, it's tiny with inline methods, so it might be good candidate for stack allocation.

Explanation / Answer

I would either return a shared_ptr or custom smart pointer, or allow automatic (stack) creation of objects. I might wrap a shared pointer in a result object if the result was large.

Whether it is the library which is processing the foo or a foo which is being processed using resources from the library depends on information you haven't provided, but typically you'd expect something like:

class Foo {
public:
Result Process ( Library& library );
};
or, if library is fixed for the lifetime of the Foo

class Foo {
public:
explicit Foo ( Library& library );
Result Process ();
};
either Result is a small struct, or if it is large then I would have it hold a smart pointer to the data.

I would throw an exception if Process failed. Given new throws an exception on failure, as do many standard C++ functions, people who don't like exceptions probably shouldn't be working in C++.

If it is expected that process could return an invalid result, then instead of an exception I would add a function to the result to test its validity, and possibly a conversion to bool so you could write

Result res ( foo.Process() );

if ( res.IsValid() ) {
...
}
or

if ( res ) {
...
}
Accessing data from an invalid result would throw an exception.