You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.
With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):
SomeResource* SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return &(*it); return NULL; }Using
std::pairwith aboolto indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return std::make_pair(*it, true); return std::make_pair(SomeResource(), false); }Using
boost::optional:boost::optional<SomeResource> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return *it; return boost::optional<SomeResource>(); }
If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.
I also modified your example so you're not searching the map twice (by reusing the iterator).
Answer from Sven on Stack OverflowYou cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.
With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):
SomeResource* SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return &(*it); return NULL; }Using
std::pairwith aboolto indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return std::make_pair(*it, true); return std::make_pair(SomeResource(), false); }Using
boost::optional:boost::optional<SomeResource> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return *it; return boost::optional<SomeResource>(); }
If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.
I also modified your example so you're not searching the map twice (by reusing the iterator).
Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)
References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".
Returning reference of NULL pointer
pointers - Why is there no "NULL reference" in C++? - Stack Overflow
Assigning return value of a function to - C++ Forum
What does it mean to do a "null check" in C or C++? - Software Engineering Stack Exchange
In following function I'm trying find a node in Binary tree that matches the key. I'm passing reference node pointer as smart pointer and this function returns a refernce to node pointer.
How can I return NULL ? As the return value of function is std::unique_ptr<node>& so it is supposed to return a reference.
std::unique_ptr<node>& BST::ReturnNodePrivate(const int& key, std::unique_ptr<node> &ptr){
if(NULL != ptr){
if(ptr->key == key){
return ptr;
}
}
else{
return NULL;
}
}
How can I return NULL ?
Because a reference carries the semantic that it points to a valid memory address that never changes; i.e. that dereferencing it is safe/defined and so no NULL checks are required. References cannot be reassigned by design.
You use a pointer when the var can be NULL and client code has to handle that case. You use a reference when you can guarantee a valid/initialised memory address.
One example of using pointers is as a member of a class to store a "reference" to some instance that might not be known or able to be initialised at class construction time. However, member references must be initialised at construction time (via initialiser lists) and their assignment cannot be deferred.
If you allow a null reference it is then no different to a pointer besides syntax (the same NULL checks would need to take place.)
Update:
"And, in most OOP languages, objects can be NULL - Pascal, C#, Java, JavaScript, PHP, etc. [...] So why is C++ somehow special and doesn't have a NULL object? Was it just an overlook or an actual decision?"
I think you are a bit confused about this. Java and C# etc. might give the impression of "NULL objects", but these object references are more or less like a C++ pointer with simpler syntax, GC instrumentation and exception throwing. In those languages if you operate on a "Null Object" you will get some kind of exception like NullReferenceException (C#). Hell, in Java its called a NullPointerException.
You have to check for null before you can use them safely. Kind of like C++ pointers (except in most managed languages, pointers are initialised to NULL by default, whereas in C++ its usually up to you to take care of setting the initial pointer value (otherwise undefined/whatever memory was already there)).
The C++ view is about having choice, and hence being verbose:
- Use a plain pointer to do how you please, checking NULL where necessary.
- Use references which have a compiler-enforced validity semantic/constraint.
- Roll your own smart pointers that do bookkeeping and behave whichever way you want them to.
- Using void pointers (cautiously!) to reference an untyped block of memory if ever required.
Please have a look at differences between pointers and references - while the standard leaves it open how references are implemented, they are at the moment always implemented as pointers.
Which means that the main difference between them is a) semantics b) pointers can be reseated c) pointers can be null.
So the short answer is, this was done on purpose. When you as programmer see a reference you should know that a) that reference is populated b) it won't change (and c) you can use it with the same semantics as an object).
Would the standard allow a null reference, you would always have to check for null before using a reference, which was not wanted.
Edit:
Regarding your edit, I guess the confusion here might stem from the fact that most simpler OO languages hide what is going on. To take Java as example, while it looks like you have NULL objects, and can assign them, you really can't - what is really going on is that Java only has pointers, and can assign null values to those pointers. Since it is impossible to actually have objects directly in Java, they do away with pointer semantics and treat the pointer as the object. C++ is simply more powerful - and error prone (Java enthusiast would say that stack user class instances are not required, and the decision to not have them in Java was driven to reduce complexity, and make Java easier to use). It also follows that, since Java doesn't have objects, it doesn't have references. What really doesn't help, though, is that Java calls what a C++ person would call a pass-by-value of a pointer a pass-by-reference.
In C and C++, pointers are inherently unsafe, that is, when you dereference a pointer, it is your own responsibility to make sure it points somewhere valid; this is part of what "manual memory management" is about (as opposed to the automatic memory management schemes implemented in languages like Java, PHP, or the .NET runtime, which won't allow you to create invalid references without considerable effort).
A common solution that catches many errors is to set all pointers that don't point to anything as NULL (or, in correct C++, 0), and checking for that before accessing the pointer. Specifically, it is common practice to initialize all pointers to NULL (unless you already have something to point them at when you declare them), and set them to NULL when you delete or free() them (unless they go out of scope immediately after that). Example (in C, but also valid C++):
void fill_foo(int* foo) {
*foo = 23; // this will crash and burn if foo is NULL
}
A better version:
void fill_foo(int* foo) {
if (!foo) { // this is the NULL check
printf("This is wrong\n");
return;
}
*foo = 23;
}
Without the null check, passing a NULL pointer into this function will cause a segfault, and there is nothing you can do - the OS will simply kill your process and maybe core-dump or pop up a crash report dialog. With the null check in place, you can perform proper error handling and recover gracefully - correct the problem yourself, abort the current operation, write a log entry, notify the user, whatever is appropriate.
The other answers pretty much covered your exact question. A null check is made to be sure that the pointer you received actually points to a valid instance of a type (objects, primitives, etc).
I'm going to add my own piece of advice here, though. Avoid null checks. :) Null checks (and other forms of Defensive Programming) clutter code up, and actually make it more error prone than other error-handling techniques.
My favorite technique when it comes to object pointers is to use the Null Object pattern. That means returning a (pointer - or even better, reference to an) empty array or list instead of null, or returning an empty string ("") instead of null, or even the string "0" (or something equivalent to "nothing" in the context) where you expect it to be parsed to an integer.
As a bonus, here's a little something you might not have known about the null pointer, which was (first formally) implemented by C.A.R. Hoare for the Algol W language in 1965.
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
I am very sure that someone told me once that NULL is defined as a pointer to void. I leafed through the K&R, and NULL was just said to be interchangeable with zero.
But either way, if I have a function that returns a 3d char array (array of arrays of strings), can I then return NULL if something goes wrong? will it be a valid return type?
Many functions that return pointers return NULL if something goes wrong - fopen for instance where you check for NULL and then perror.
But I am confused about multi-dimensional pointers.
I mean, I know that they are technically just pointers. I am unsure what the multiple asterisks do except tell the programmer how many dimensions there are. Hmmm Is this the solution?
Comments?
This code doesn't work, though it may appear to work. This line dereferences a null pointer:
return *static_cast<MyType*>(0);
The zero, cast to a pointer type, results in a null pointer; this null pointer is then dereferenced using the unary-*.
Dereferencing a null pointer results in undefined behavior, so your program may do anything. In the example you describe, you get a "null reference" (or, it appears you get a null reference), but it would also be reasonable for your program to crash or for anything else to happen.
I agree with other posters that the behaviour of your example is undefined and really shouldn't be used. I offer some alternatives here. Each of them has pros and cons
- If the object can't be found, throw an exception which is caught in the calling layer.
- Create a globally accessible instance of
MyTypewhich is a simple shell object (i.e.static const MyType BAD_MYTYPE) and can be used to represent a bad object. - If it's likely that the object will not be found often then maybe pass the object in by reference as a parameter and return a bool or other error code indicating success / failure. If it can't find the object, you just don't assign it in the function.
- Use pointers instead and check for 0 on return.
- Use Boost smart pointers which allow for the validity of the returned object to be checked.
My personal preference would be for one of the first three.
I just have to get this rant off my chest, since I've received a few comments about it on both my blog and an associated Reddit post.
Maybe I'm preaching to the choir. Maybe I'm feeding trolls. I'll assume that there are those out there who, in good faith, really don't understand that C++ references are not nullable.
Many other languages made the fatal error of permitting null as valid for all reference types, where every non-builtin is a reference type and they have boxing around classes. Here's some psuedo-Java:
class MyType {
public void foo() {}
};
void my_fun(MyType instance) {
instance.foo(); // <-- MAY THROW
}
void another_fun() {
my_fun(null); // <-- explodes
}This is semantically similar to the following C++:
class MyType {
public:
void foo() {}
}
void my_fun(MyType* instance) {
__check_nonnull(instance); // <-- Check inserted by compiler
instance->foo();
}
void another_fun() {
my_fun(nullptr);
}
With implicitly nullable references, every single use of the reference is a candidate for a nullptr.
On the contrary, C++ affords the guarantee that a T& always refers to a valid T.
Of course, all of C++'s guarantees have a caveat: Every guarantee goes out the window if any part of a program contains undefined behavior.
Here's a common "C++ null reference" example that detractors provide:
class MyClass {
public:
void foo();
};
void do_thing(MyClass& inst) {
inst.foo();
}
void other_thing() {
MyClass* inst_ptr = nullptr;
do_thing(*inst_ptr);
}
Of course, the fact that we dereference inst_ptr means the program behavior is undefined. The call inst.foo() is perfectly legal, and checking that &inst != nullptr is unnecessary.
In fact, the very expression &<anything> != nullptr is completely non-sensical. C++ guarantees that the builtin address-of operator& never returns nullptr. We even get a warning about it from GCC.
Saying "impossible thing might happen" is not useful. Imagine this code:
class MyClass {
public:
void foo();
};
class UnrelatedClass {
public:
void foo();
}
void do_thing(MyClass& inst) {
inst.foo();
}
Saying "inst might be a null reference" is equivalent to saying "inst might actually be an UnrelatedClass" because someone might do this:
void garbage_fn() {
UnrelatedClass garbage;
do_thing(reinterpret_cast<MyClass&>(garbage));
}Both cases are undefined, but for some reason, people still believe that null-references are a thing.
Edit: Wording
Edit to clarify:
I'm not saying that dereferencing null pointers never occurs in practice. What I'm really saying is that there is no use in worrying if a client has dereferenced a null pointer in order to fulfill a reference parameter on your API. There's no meaningful action that you can take.
Just like this is never null. In fact, GCC will remove checks for null this because it can never be null.
The important point here is that you should never, ever, ever, ever check if a reference (or this) has the value of the null pointer. What could you possibly do that would be correct in that case? If you get to the point where a reference has the value of the null pointer your program is already borked. You can't fix it. Knowing how to fix it would imply that you knew about the bug somewhere else in your program that allowed the reference to contain the value of the null pointer. If you did know what that bug was you would simply fix that bug.
While freeing memory, this is how I proceeded:
// Free `p` and all ancestors of `p`.
void free_family(person *p)
{
// TODO: Handle base case
if (p == NULL)
{
return NULL;
}It appears (ChatGPT) that the following will be the correct way:
// Free `p` and all ancestors of `p`.
void free_family(person *p)
{
// Handle base case
if (p == NULL)
{
return;
}In the context of freeing memory, you typically don't return anything (NULLor otherwise) because you are modifying memory, not producing a result (ChatGPT).
The distinction seems subtle and somewhat vague though makes sense.
Source: https://learning.edx.org/course/course-v1:HarvardX+CS50+X/home
In C++, references can't be null. If you want to optionally return null if nothing is found, you need to return a pointer, not a reference:
Attr *getAttribute(const string& attribute_name) const {
//search collection
//if found at i
return &attributes[i];
//if not found
return nullptr;
}
Otherwise, if you insist on returning by reference, then you should throw an exception if the attribute isn't found.
(By the way, I'm a little worried about your method being const and returning a non-const attribute. For philosophical reasons, I'd suggest returning const Attr *. If you also may want to modify this attribute, you can overload with a non-const method returning a non-const attribute as well.)
There are several possible answers here. You want to return something that might exist. Here are some options, ranging from my least preferred to most preferred:
Return by reference, and signal can-not-find by exception.
Attr& getAttribute(const string& attribute_name) const { //search collection //if found at i return attributes[i]; //if not found throw no_such_attribute_error; }
It's likely that not finding attributes is a normal part of execution, and hence not very exceptional. The handling for this would be noisy. A null value cannot be returned because it's undefined behaviour to have null references.
Return by pointer
Attr* getAttribute(const string& attribute_name) const { //search collection //if found at i return &attributes[i]; //if not found return nullptr; }
It's easy to forget to check whether a result from getAttribute would be a non-NULL pointer, and is an easy source of bugs.
Use Boost.Optional
boost::optional<Attr&> getAttribute(const string& attribute_name) const { //search collection //if found at i return attributes[i]; //if not found return boost::optional<Attr&>(); }
A boost::optional signifies exactly what is going on here, and has easy methods for inspecting whether such an attribute was found.
Side note: std::optional was recently voted into C++17, so this will be a "standard" thing in the near future.
If the function checks the index then a general approach in such a case is to throw an exception std::out_of_range.
Take into account that there is already the member function at in the class template std::vector.
If you may not use exceptions and the task is
P.S. Original task is searching item with property equal to.
then you can use either the standard algorithm std::find_if that returns an iterator or you can write your own function that returns the index that corresponds to the searched element. If there is no such an element then return the size of the vector, For example
#include <iostream>
#include <vector>
template <typename Predicate>
std::vector<int>::size_type find_if( const std::vector<int> &v, Predicate predicate )
{
std::vector<int>::size_type i = 0;
while ( i != v.size() && !predicate( v[i] ) ) ++i;
return i;
}
int main()
{
std::vector<int> items = {1, 2, 5, 0, 7};
auto i = ::find_if( items, { return item % 2 == 0; } );
if ( i != items.size() ) std::cout << items[i] << '\n';
return 0;
}
C++ has value semantics. There are nullptrs but there is no null value. A reference always references something. Ergo, there cannot be a reference to null.
Several options you have:
- throw an exception. Your argument for rejecting them is moot.
std::vector::atdoes exactly that (but I suppose your code is just an example for a more general situation) - return a pointer that can be
nullptr(not recommended, because then you put the resonsibility on handling it correctly on the caller) - return a
std::optional. Again this forces the caller to handle the case of "no value returned" but in contrast to returning anullptrthe caller gets a well-designed interface that is hard to use wrong. - return an iterator.
endis often used to signal "element not found" throughout the standard library, so there will be little surprise if you do the same. - perhaps this is not just an example for a different situation, then you should use
std::vector::atinstead of your handwritten function and be done with it.
P.S. Original task is searching item with property equal to.
You should use std::find to find an item in a container. It returns end of the container when the element cannot be found.