evazkj
1/11/2019 - 4:04 PM

C++ Pointers

Smart Pointer

  • Smart pointers can be used to
    • Manage shared ownership
    • Model unique ownership
    • Ensure correct deletion of dynamically allocated memory
    • Break pointer cycles
    • Communicate intention, i.e., self-documenting code

Managed Pointer

  • Models unique ownership
  • 在做assignment的时候不再是copy而是move
  • 通常在我们不希望一个object outlive当前function的时候使用
  • Owns a dynamically allocated object
  • Automatically deletes the memory when it goes out of scope
  • Helps reduce memory management problems:
    • Memory leaks
    • Dangling pointers
  • Syntx:
template <typename T>  // custom delete function
void arrayDeleter(T *ptr, void *cookie) 
{ delete [] ptr; }
...
using BloombergLP::bslma::ManagedPtr;
// a shared pointer to an array, with custom deleter, and cookie is an argument for deleter 
ManagedPtr<Bond> guard(new Bond[10], NULL,&arrayDeleter<Bond>);
// on clean-up the custom deleter is called
  • When use it to manage an array, you need to feed in a deleter.

Shared Pointer

  • 用来处理多个pointer指向同一个dynamic memory的情况
  • Behavior: Reference counted pointer(记录被reference的次数),只有在count归零时 删除资源。
  • Syntx:
#include <bsl_memory.h>
class C {}

  bsl::shared_ptr<C> p(new C(arg1, arg2));
  bsl::shared_ptr<C> q; 
  bsl::shared_ptr<C> r = bsl::make_shared<C>(arg1, arg2); // without using new, preferred way
  • Shared pointers are generally passed by value
  • Pitfall:
    1. Raw pointer aliasing causes problem!
C *rawPtr = new C();
bsl::shared_ptr<C> p(rawPtr);
bsl::shared_ptr<C> q(rawPtr);

Moral: Don’t use the same raw pointer to initialize two shared pointers, Avoid having both shared pointers and raw pointers pointing to the same object

  1. CYCLES ARE NOT DE-ALLOCATED
class C {
  bsl::shared_ptr<C> d_next;
  ...
};
bsl::shared_ptr<C> p(new C);
bsl::shared_ptr<C> q(new C);
bsl::shared_ptr<C> r(new C);
p->setNext(q);
q->setNext(r);
r->setNext(p);
p.reset();
q.reset();
r.reset();
  • 不把counter降为0,不能trigger destructor of C,但同时,不destruct C无法将任何 一个ref pointer降为0,陷入死循环

Weak Pointer

  • A smart pointer template that holds a non-owning, i.e., weak, reference to an object managed by a shared pointer
  • Does not participate in the shared pointer's reference count
  • The referred object may be deleted at any time and the weak reference expires
  • Models temporary ownership, i.e., must be converted to a shared pointer to access the referenced object, this guarantees reference remains valid during the access Can be used to break circular references of shared pointers
  • Syntx
bsl::shared_ptr<Bond> b = bsl::make_shared<Bond>(…);
bsl::weak_ptr<Bond> weakb(b); // create a weak pointer to b
bsl::shared_ptr<Bond> tempb = weakb.lock();
  // convert to shared pointer to access/use it
tempb.reset(); // finished, usually just goes out of scope
b.reset(); // release original shared pointer
if (weakb.expired()) {
  // weak pointer is expired when target shared pointer
  // has been deleted
    bsl::cout << "GONE!\n";}