Raw Pointers
// As defined in C
int *p = new int(); //p is raw pointer.
Smart pointers
-
Automatically deletes the allocated memory when Object goes out of
scope.
Allocate memory in ctr, Delete memory in dtr. Bcoz Destructors are automatically executed when Object goes out of scope.
Programmer may allocate memory using new() & later might forget to use delete().
Smart Pointer Implementation Example
template <class T>
class A{ //This class is Smart pointer
T *a; //int *a;
public:
A(T *r) : a(r) { cout << "Allocated\n"; } //A(int *r):a(r)
~A(){
delete a;
cout << "Freed\n";
}
T &operator *(){ //int &operator *() //& returns a only, does not create new copy
return *a;
}
};
int main(){
//Automatic template type deduction => Provided in C++17
A <int> obj(new int()); //obj is my pointer now. I can carry all pointer operations
*obj = 10;
cout << *obj;
A <float> obj1(new float());
}
# g++ smart_pointers
Allocated
10
Allocated
Freed
Freed
Unique vs Shared pointer (Both are types of Smart Pointers)
| Unique | Shared | |
|---|---|---|
| What | Only 1 Owner of memory, ie only 1 pointer to an object | Multiple owners of a resource |
| Copy Constructible |
No There can be only one unique_ptr to any resource, any attempt to make a copy of a unique_ptr will cause a compile-time error.
|
Yes
|
| Move Constructible |
Yes
|
Yes Multiple pointers can point to same resource, Owner count is maintained using reference counting When none is referencing the memory, it's deleted automatically
|
| Creation | Using make_shared | Using make_shared |
How shared_ptr is implemented internally?
-
shared_ptr maintains 2 things.
Creation of shared_ptr: reference_count=1
On every new shared_ptr creation: reference_count++
Deletion/Reset: reference_count--
int reference_count;
T* data; //and a pointer to the object being shared
template <typename T>
class shared_ptr {
struct ControlBlock { //stores a pointer to the object being shared (T* ptr_) and a reference count (int ref_count_).
T* ptr_;
int ref_count_;
};
ControlBlock* data_;
public:
shared_ptr(T* ptr) {
data_ = new ControlBlock;
data_->ptr_ = ptr;
data_->ref_count_ = 1;
}
shared_ptr(const shared_ptr& other) {
data_ = other.data_;
data_->ref_count_++;
}
~shared_ptr() {
if (--data_->ref_count_ == 0) {
delete data_->ptr_;
delete data_;
}
}
};