Reputation: 36205
I am fairly new to C++ and I'm working on a project where I have a method which is declared as follows:
SupportTicket SupportProcessor::getSupportTicket(int supportRef)
The method above look for a record in the database and if found will return an object of type SupportTicket
. However, if it is now found, either because the supportRef wasn't found, or because of a database error, I want to return nothing, i.e. NULL
. Although the method itself doesn't complain, when I then check to see if the value returned is NULL I get an error.
For example, I am calling my method as below:
SupportTicket supportTicket = this->getSupportTicket(1);
if (supportTicket != NULL)
{
//The record was found
}
else
{
//The record was not found or an error occurred
}
The error I am getting back is:
no operator "!=" matches these operands
binary '!=' no operator found which takes a left-hand operand of type 'SupportTicket' (or there is no acceptable conversion)
In the method getSupportTicket, I've tried both returning NULL and nullptr
I come from a C# background so this is completely fine normally so how would I do this in c++. I know in the method, I could allocate the return value on the heap by doing return new SupportTicket()
and then deleting it in the method where it gets returned to, but this seems a little overkill, or is this the only way to do it.
Upvotes: 1
Views: 79
Reputation: 50540
First of all, the error. It's probably due to the fact that your SupportTicket
class cannot be compared neither with NULL
nor with nullptr
. I cannot even figure out how you return a null ticket from your function, for it cannot be easily deduced from the code you posted.
Anyway, C++ is pretty different from other languages like C# or Java and you cannot simply return a null reference from a function to indicate that you don't want to/you can't return an object of the specified type.
In case SupportTicket
supports two valid states, something like correctly initialized and definitely uninitialized, you can define the operator bool()
for that class or a isValid
member function and use them directly in a guard as:
if(myTicket) {
// ...
}
Or:
if(myTicket.isValid()) {
// ...
}
In C++17 you can use an std::optional
instead for your return type:
The class template std::optional manages an optional contained value, i.e. a value that may or may not be present.
It has an operator bool()
to test whether the object has been properly initialized or not. See the linked documentation for further details.
In C++11/14 you can use an std::unique_ptr<SupportTicket>
and return an uninitialized pointer in case of failure. The drawback is that you must create the object itself on the dynamic storage. If it's fine or not for you mostly depends on the actual problem, I cannot say that.
Otherwise, you can look for an alternative implementation of std::optional
on github (here is an example) or refer to <experimental/optional>
if your compiler offers it.
A slightly less user-friendly solution is to throw an exception, but it forces the caller to embed any invokation within a try/catch
block and it's usually quite annoying.
Upvotes: 2