In a couple of my older code projects when I had never heard of smart pointers, whenever I needed to check whether the pointer still pointed to a valid object, I would alway
In C, anything that's not 0 is true. So, you certainly can use:
if (ptrToObject)
ptrToObject->doSomething();
to safely dereference pointers.
C++11 changes the game a bit, nullptr_t is a type of which nullptr is an instance; the representation of nullptr_t is implementation specific. So a compiler may define nullptr_t however it wants. It need only make sure it can enforce proper restriction on the casting of a nullptr_t to different types--of which boolean is allowed--and make sure it can distinguish between a nullptr_t and 0.
So nullptr will be properly and implicitly cast to the boolean false so long as the compiler follows the C++11 language specification. And the above snippet still works.
If you delete a referenced object, nothing changes.
delete ptrToObject;
assert(ptrToObject);
ptrToObject = nullptr;
assert(!ptrToObject);
Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling it's members.
No. Please maintain a proper graph of objects (preferably using unique/smart pointers). As pointed out, there's no way to determine if a pointer that is not nullptr points to a valid object or not. The onus is on you to maintain the lifecycle anyway.. this is why the pointer wrappers exist in the first place.
In fact, because the life-cycle of shared and weak pointers are well defined, they have syntactic sugar that lets you use them the way you want to use bare pointers, where valid pointers have a value and all others are nullptr:
Shared
#include
#include
void report(std::shared_ptr ptr)
{
if (ptr) {
std::cout << "*ptr=" << *ptr << "\n";
} else {
std::cout << "ptr is not a valid pointer.\n";
}
}
int main()
{
std::shared_ptr ptr;
report(ptr);
ptr = std::make_shared(7);
report(ptr);
}
Weak
#include
#include
void observe(std::weak_ptr weak)
{
if (auto observe = weak.lock()) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}
int main()
{
std::weak_ptr weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);
{
auto shared = std::make_shared(42);
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
}
std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}
Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?
So to answer the question: with bare pointers, no. With wrapped pointers, yes.
Wrap your pointers, folks.