📖
Go C++
  • Introduction
  • Chapter 1: What You Must Know First
    • Virtual Address Space of Process: Memory Partition and Layout
    • Function Call: Stack Frame
    • Program Compiling and Linking
  • Chapter 2: C++ Basics Improvement
    • Default Parameters
    • Inline Function
    • Function Overloading
    • new and delete
    • const and Pointers
    • References in Detail
  • Chapter 3: Object-Oriented Principles
  • Class and Object
  • Constructor and Destructor
  • Shallow Copy and Deep Copy
  • Initializer List
  • Various Member Functions
  • Pointer to Class Members
  • Chapter 4: Template Programming
  • Function Templates
  • Class Templates
  • Memory Allocators
  • Chapter 5: Operator Overloading
    • Operator Overloading
    • Introduction to Iterators
    • Issues of Iterator Invalidation
    • More about new and delete
    • Overloading of new and delete: Object Pool
  • Chapter 6: Inheritance and Polymorphism
    • Look inside Inheritance
    • More about Inheritance
    • Virtual Functions, Static Binding and Dynamic Binding
    • More about Virtual Functions
    • Understanding Polymorphism
    • Abstract Classes
    • Frequently Asked Interview Questions: Polymorphism
  • Chapter 7: Multiple Inheritance
    • Virtual Inheritance and Virtual Base Classes
    • Diamond Problem
    • Four Kinds of Type Conversions
  • Chapter 8: Standard Template Library
    • Sequence Containers
    • Container Adaptors
    • Associative Containers
    • More about Iterators
    • Function Objects
    • Generic Algorithms, Binders and Lambda Expressions
  • Chapter 9: Object Optimization
    • Behind the Object
    • Optimizing Objects in Functions
    • Member Functions with Rvalue References
    • Move Semantics and Perfect Forwarding
  • Chapter 10: Smart Pointers
    • Smart Pointers
    • Smart Pointers without Reference Counting
    • Smart Pointers with Reference Counting
    • Custom Deleters
  • Chapter 11: Function Objects and Binders
    • More about Binders
    • Introduction to std::function
    • Template Specialization and Argument Deduction
    • More about std::function
    • std::bind(): A Simple Thread Pool
    • More about Lambda Expressions
  • Chapter 12: Multithreading
    • Important Features in C++11
    • Multithreaded Programming with std::thread
    • Mutual Exclusion
    • Producer-Consumer Problem
    • Atomic Operations
    • Thread Visibility and volatile
  • Chapter 13: Design Patterns
    • Singleton Pattern
    • Factory Pattern
    • Proxy Pattern
    • Decorator Pattern
    • Adapter Pattern
    • Observer Pattern
Powered by GitBook
On this page

Was this helpful?

  1. Chapter 10: Smart Pointers

Smart Pointers

Pointers are the most powerful tools in C++, but programmers have to be responsible for the management of memory allocated on the heap. Any objects created with new has to be destroyed with delete, otherwise a memory leak will happen. Is there a way that the pointer can be automatically deleted when the memory is no longer used? The answer is yes. We can use object-oriented programming to implement a simplest smart pointer.

Here we defined a template class SmartPtr which keeps a normal pointer as its member variable. The constructor simply initializes the pointer, while the destructor deletes it.

template <typename T>
class SmartPtr {
public:
    SmartPtr(T *ptr = nullptr) : _ptr(ptr) {}
    ~SmartPtr() {delete _ptr;}
private:
    T *_ptr;
}

Now our smart pointer can be automatically deleted, taking use of the feature that objects on the function stack are automatically destroyed when they get out of the scope.

int main() {
    SmartPtr<int> p(new int);
    return 0;
}

To achieve full functionality of a pointer, we need to provide the dereference and the arrow as well.

template <typename T>
class SmartPtr {
    ...
    T& operator*() {return *_ptr;}
    T* operator->() {return _ptr;}
}

So far, out smart pointer works perfectly, but a problem occurs with the copy constructor:

int main() {
    SmartPtr<int> p1(new int);
    SmartPtr<int> p2(p1);
    return 0;   // ERROR
}

The program goes wrong when it returns. Here our copy constructor is a shallow copy, which only copies the pointer. When p1 and p2 is destroyed, the memory is deallocated repeatedly. Of course, we can rewrite the copy constructor to implement a deep copy, but in most circumstances we only want p1 and p2 pointing to a same object.

There are two ways to solve the shallow copy problem, with or without the reference counting. In next articles, we will introduce different kinds of smart pointers in C++ utilities library.

PreviousMove Semantics and Perfect ForwardingNextSmart Pointers without Reference Counting

Last updated 4 years ago

Was this helpful?