Why do C++ libraries and frameworks never use smart pointers?

后端 未结 8 719
时光取名叫无心
时光取名叫无心 2020-12-22 15:09

I read in a few articles that raw pointers should almost never be used. Instead they should always be wrapped inside smart pointers, whether it\'s scoped or shared pointers.

相关标签:
8条回答
  • 2020-12-22 16:05

    There can be many reasons. To list few of them:

    1. Smart pointers became part of standard just recently. Till then they were part of other libraries
    2. Their primary use is to avoid memory leaks; many libraries don't have their own memory management; Generally they provide utilities and APIs
    3. They are implemented as wrapper, since they are actually objects and not pointers. Which has additional time/space cost, compared to raw pointers; The users of the libraries may not want to have such overheads

    Edit: Using smart pointers is a completely developer's choice. It depends on various factors.

    1. In performance critical systems, you may not want to use smart pointers which generates overhead

    2. The project which needs the backward compatibility, you may not want to use the smart pointers which has C++11 specific features

    Edit2 There is a string of several downvotes in the span of 24 hours because of below passage. I fail to understand why the answer is downvoted even though below is just an add-on suggestion and not an answer.
    However, C++ always facilitates you to have the options open. :) e.g.

    template<typename T>
    struct Pointer {
    #ifdef <Cpp11>
      typedef std::unique_ptr<T> type;
    #else
      typedef T* type;
    #endif
    };
    

    And in your code use it as:

    Pointer<int>::type p;
    

    For those who say that a smart pointer and a raw pointer are different, I agree with that. The code above was just an idea where one can write a code which is interchangeable just with a #define, this is not compulsion;

    For example, T* has to be deleted explicitly but a smart pointer does not. We can have a templated Destroy() to handle that.

    template<typename T>
    void Destroy (T* p)
    {
      delete p;
    }
    template<typename T>
    void Destroy (std::unique_ptr<T> p)
    {
      // do nothing
    }
    

    and use it as:

    Destroy(p);
    

    In the same way, for a raw pointer we can copy it directly and for smart pointer we can use special operation.

    Pointer<X>::type p = new X;
    Pointer<X>::type p2(Assign(p));
    

    Where Assign() is as:

    template<typename T>
    T* Assign (T *p)
    {
      return p;
    }
    template<typename T>
    ... Assign (SmartPointer<T> &p)
    {
      // use move sematics or whateve appropriate
    }
    
    0 讨论(0)
  • 2020-12-22 16:05

    Good question. I don't know the specific articles to which you refer, but I have read similar things from time to time. My suspicion is that the writers of such articles tend to harbor a bias against C++-style programming. If the writer programs in C++ only when he must, then returns to Java or such as soon as he can, then he doesn't really share the C++ mindset.

    One suspects that some or most of the same writers prefer garbage-collecting memory managers. I don't, but I think differently than they do.

    Smart pointers are great, but they have to keep reference counts. The keeping of reference counts bears costs -- often modest costs, but costs nonetheless -- at runtime. There is nothing wrong with saving these costs by using bare pointers, especially if the pointers are managed by destructors.

    One of the excellent things about C++ is its support for embedded-systems programming. The use of bare pointers is part of that.

    Update: A commenter has correctly observed that C++'s new unique_ptr (available since TR1) does not count references. The commenter also has a different definition of "smart pointer" than I have in mind. He may be right about the definition.

    Further update: The comment thread below is illuminating. All of it is recommended reading.

    0 讨论(0)
提交回复
热议问题