Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would I want to use a smart pointer in this situation?

I never used any kind of smart pointer, but I keep reading about them almost everywhere when the topic is pointers. I do understand that there are situations where smart pointers are much nicer to work with than raw pointers, because to some extend they manage ownership of the pointer. However, I still do not know, where is the line between "I do not needing smart pointers for that" and "this is a case for smart pointers".

Lets say, I have the following situation:

class A {
public:
    double get1(){return 1;}
    double get2(){return 2;}
};
class SomeUtilityClass {
public:
    SomeUtilityClass(A* a) : a(a) {}
    double getResult(){return a->get1() + a->get2();}
    void setA(A* a){a = a;}
private:
    A* a;
};
int main(int argc, char** argv) {
    A a;
    SomeUtilityClass u(&a);
    std::cout << u.getResult() << std::endl;
    A a2;
    u.setA(&a2);
    std::cout << u.getResult() << std::endl;
    return 0;
}

This is of course an oversimplified example. What I mean is that SomeUtilityClass is not supposed to "own" an instance of A (because it is just a utility class), thus it just holds a pointer.

Concerning the pointer, the only thing that I am aware of that could go wrong is:

  • SomeUtilityClass can be instantiated with a null pointer
  • The object pointed to may be deleted/go out of scope, without the SomeUtilityClass noticing it

How could a smart pointer help to avoid this problem? What other benefits I would get by using a smart pointer in this case?

PS: I know that there are several question on smart pointers (e.g. this one). However, I would appreciate, if you could tell me about the impact on this particular example.

like image 667
463035818_is_not_a_number Avatar asked May 04 '15 13:05

463035818_is_not_a_number


People also ask

What is a smart pointer why it is used and describe the types?

Smart pointers are just classes that wrap the raw pointer and overload the -> and * operators; this allows them to offer the same syntax as a raw pointer. C++11 has three types of smart pointers that are defined in the <memory> header of the Standard Library. They are: std::unique_ptr. std::shared_ptr.

In what kind of circumstances would you use a raw pointer instead of a smart pointer?

The rule would be this - if you know that an entity must take a certain kind of ownership of the object, always use smart pointers - the one that gives you the kind of ownership you need. If there is no notion of ownership, never use smart pointers.

Which smart pointer should be used when you want shared ownership but not reference counting?

If you find that you need to share data or utilize reference counting, you should use a std::shared_ptr . If you need to reference shared data but don't want to contribute to the reference count, use a std::weak_ptr .

What is the difference between a smart pointer and a normal pointer?

A Smart Pointer is a wrapper class over a pointer with an operator like * and -> overloaded. The objects of the smart pointer class look like normal pointers. But, unlike Normal Pointers it can deallocate and free destroyed object memory.


1 Answers

This depends on how the parameter is created and stored. If you don't own the memory and it could be either statically or dynamically allocated, a raw pointer is a perfectly reasonable solution -- especially if you need to support swapping of the data as in your example. Another option would be to use std::reference_wrapper, which would get rid of your nullptr issue whilst keeping the same semantics.

If you are holding a pointer to some shared resource (i.e. stored in a std::shared_ptr somewhere) and want to be able to check if it has been deleted or not, you could hold a std::weak_ptr.

like image 54
TartanLlama Avatar answered Nov 15 '22 05:11

TartanLlama