DigestCPP

Lets Understand With Example

  • Home
  • Design Principal
  • Design Patterns
  • C++ 11 Features
  • C++11 Multithreading
  • Contact Us

unique pointer c++11

std::unique_ptr

It is smart pointer, it is a part of C++11. It owns the object and in other word it implements the “exclusive ownership” (two pointer cannot point to same object). Technically std::unique_ptr is a class template and class template contains raw pointer and this raw pointer points to one object at a time but ownership can be transferred.

Problem with raw pointer:

  • memory leak  can happen (if forget to add “delete” or exception occurs before delete).
  • dangling pointer can be created.
  • multiple delete error can be happened.

key points of unique pointer:

  • exclusive ownership.
  • avoid memory leak.
  • do proper clean up.
  • can NOT do copy operation.
  • can NOT do assignment operation.
  • can do only move operations (transfer ownership).
  • If we want to return the unique pointer from function then just return it (internally it will use move operation so no need to worry).
  • No arithmetic operation permitted.
  • unique pointer can be empty.
  • simple interface and make less error prone.

Creation of an unique pointer:

{//type is int
std::unique_ptr<int>up{new int{5}};  
//type is std::string
std::unique_ptr<std::string>up1{new std::string{"digestcpp"}};
//type is int[] 
std::unique_ptr<int[]>up2{new int[3]{1,2,3}};
//type is user defined data type (class), A is class
std::unique_ptr<A> up3{new A};
//empty pointer
std::unique_ptr<int> up4();
//old c++ initialization
std::unique_ptr<int> up5(new int(5));
}//destructor will be called and heap memory will be released

Restriction inside unique pointer (below operations are not permitted):

  • copy operation is prohibited (copy constructor is declared as “deleted function”)
  • Assignment operator is prohibited (copy constructor is declared as “deleted function”)
std::unique_ptr<int> up{new int{5}};
std::unique_ptr<int> up4{up};//if we try copy operation then compiler will give below error
std::unique_ptr<int> up5{};
up5=up;                      //if we Assignment operator then compiler will give below error
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&)

Access the object in unique pointer (please check below example):

  • deference by operator* (if unique pointer manages single object then we can access the object using operator*)
  • deference by operator-> (if unique pointer manages single object then we can access the object’s member function using operator->)
  • deference by get() member function (if unique pointer manages single object then we can access the object’s pointer using get())
  • deference by operator[] (if unique pointer manages array of objects then we can access individual object using operator[])
std::unique_ptr<int> up{new int{5}};
std::cout<<"Int Value:"<<*up<<std::endl;

std::unique_ptr<std::string> up1{new std::string{"digestcpp"}};
std::cout<<"Unique pointer has -> operation:"<<up1->append(".com")<<std::endl;

std::unique_ptr<int[]> up2{new int[3]{1,2,3}};
std::cout<<"Int[0] Value:"<<up2[0]<<std::endl;

int* pIptr= up.get();//return pointer pointing to actual object
std::cout<<"Int value using get():"<<*pIptr<<std::endl;

Other functionality (like reset, release, please check below example):

  • reset() (delete the memory or resource and assign the nullptr)
  • release() (give up the ownership, without calling delete, now delete responsibility is NOT with unique_ptr)
  • get() (return the address of object, still delete responsibility with unique pointer, we can read the value.)

Header file:

#include<memory> under namespace std as std::unique_ptr

Source code with example:

/*
Program:Unique Pointer 
Author: Alpha Master
Date: 26 September 2021
*/

//Header File
#include<iostream>
#include<memory>

class A
{
};

int main()
{
    std::cout<<"Unique Pointer"<<std::endl;

    //Unique pointer has int
    std::unique_ptr<int> up{new int{5}};
    std::cout<<"Int Value:"<<*up<<std::endl;

    //Unique pointer has string
    std::unique_ptr<std::string> up1{new std::string{"digestcpp"}};
    std::cout<<"String Value:"<<*up1<<std::endl;
    std::cout<<"Unique pointer has -> operation:"<<up1->append(".com")<<std::endl;

    //Unique pointer has int[]
    std::unique_ptr<int[]> up2{new int[3]{1,2,3}};
    std::cout<<"Int[0] Value:"<<up2[0]<<std::endl;

    //Unique pointer has user defined data type
    std::unique_ptr<A> up3{new A};
    //std::cout<<"Int Value:"<<*up<<std::endl;

    //Using get() member function
    int* pIptr= up.get();
    std::cout<<"Int value using get():"<<*pIptr<<std::endl;
    if(up)
        std::cout<<"object is present"<<std::endl;
    else
        std::cout<<"No object"<<std::endl;

    //other functionality
    //release
    int* pInRe = up.release();
    if(up)
    	std::cout<<"object is present"<<std::endl;
    else
   	std::cout<<"No object"<<std::endl;

    //reset //delete the object and reset to nullptr
    up.reset(); 
   if(up)
        std::cout<<"object is present"<<std::endl;
    else
        std::cout<<"No object"<<std::endl;

    return 0;
}

Output:

Unique Pointer
Int Value:5
String Value:digestcpp
Unique pointer has -> operation:digestcpp.com
Int[0] Value:1
Int value using get():5
object is present
No object
No object

unique pointer with function: 

We want to pass the unique pointer to function that we have 2 option:

  • Pass by reference (actual object will be accessible in function)
  • Pass by actual object (Need to do std::move() while calling)

If we want to return the unique pointer from function then just return it (internally it will use move operation so no need to worry)

/*
Program:Unique Pointer with function
Author: Alpha Master
Date: 4 April 2021
*/

//Header File
#include<iostream>
#include<memory>



std::unique_ptr<int> fun1(int tmp)
{
    std::unique_ptr<int>up{new int(tmp)};
    std::cout<<"Value in fun1:"<<*up<<std::endl;
    return up;
}

void fun2(std::unique_ptr<int>& tmp)
{
   std::cout<<"Value in fun2:"<<*tmp<<std::endl;
   return;
}


std::unique_ptr<int> fun3(std::unique_ptr<int> tmp)
{
    std::cout<<"Value in fun3:"<<*tmp<<std::endl;
    return tmp;
}


int main()
{
    std::cout<<"Unique Pointer with function"<<std::endl;
    std::unique_ptr<int>A = fun1(5);
    std::cout<<"Value first time:"<<*A<<std::endl;
    fun2(A);
    std::cout<<"Value second time:"<<*A<<std::endl;
    std::unique_ptr<int>B = fun3(std::move(A));
    std::cout<<"Value third time:"<<*B<<std::endl;

    
    return 0;
}

Output:

Unique Pointer with function
Value in fun1:5
Value first time:5
Value in fun2:5
Value second time:5
Value in fun3:5
Value third time:5

 

/*
Program: Unique pointer pass to function 
Author: Alpha Master
Date: 23 September 2021
*/

//Header File
#include<iostream>
#include<memory>
#include<string>

std::unique_ptr<std::string> addSuffix(std::unique_ptr<std::string> upt)
{
    std::string temp = (*upt.get()) + " master";
    std::cout<<temp<<std::endl;
    //reset
    upt.reset(new std::string(temp));
    return upt;
}

int main()
{
    std::cout<<"Unique pointer"<<std::endl;
    //Creat new object
    std::unique_ptr<std::string> up { new std::string {"alpha"}};
    //pass this unique object to function
    std::unique_ptr<std::string> out = addSuffix(std::move(up));
    std::cout<<"Output:"<<*out.get();
    std::cout<<std::endl;
    return 0;
}

 

Unique pointer
alpha master
Output:alpha master

unique pointer with class:

/*
Program:Unique Pointer with external class
Author: Alpha Master
Date: 4 April 2021
*/

//Header File
#include<iostream>
#include<memory>



class A
{
    std::unique_ptr<int>m_upI;
    std::unique_ptr<std::string>m_upS;
    public:
    A(int i, std::string s)
    {
        std::cout<<"In A Constructor"<<std::endl;
        m_upI.reset(new int(i));
        m_upS.reset(new std::string(s));
    }
    ~A()
     { 
         std::cout<<"In B Destructor"<<std::endl;
         m_upI.reset(nullptr);
         m_upS.reset(nullptr);
     }
     int getInt()
     {
         return (*m_upI);
     }
     std::string getString()
     {    return (*m_upS);}
};

int main()
{
    std::cout<<"Unique Pointer with Class"<<std::endl;
    {
        A obj(5, "digestcpp.com");
        std::cout<<"Int:"<<obj.getInt()<<std::endl;
        std::cout<<"String:"<<obj.getString()<<std::endl;
    }
    std::cout<<"Outside Block"<<std::endl;
    return 0;
}

Own Unique Pointer class

Primary Sidebar




DigestCPP © 2023. All rights reserved.

    About Privacy Policy Terms and Conditions Contact Us Disclaimer