Use of deleted function c++: In the previous article, we have discussed about Unary Operator Overloading in CPP using both member & Friend function. Let us learn About ‘delete’ keyword and deleted functions with Use Cases in C++ Program.
Understanding the use of ‘delete’ keyword
C++ delete function: In this article we will discuss about a keyword delete
, through which we can make function incapable and ineffective.
Deleting Copy Constructor and Assignment Operator :
Error: use of deleted function: We can’t call a deleted function if we do so, then it will generate compile time error.
#include <iostream> #include <string> class Student { int sroll; std::string sname; public: Student(int studRoll, std::string studName) : sroll(studRoll), sname(studName) {} // to delete the Copy Constructor Student(const Student & obj) = delete; // to delete the Assignment operator Student & operator = (const Student & obj) = delete; void display() { std::cout<<sroll << " ::: "<<sname<<std::endl; } }; int main() { Student userObj(10, "Rick"); Student obj = userObj; return 0; }
Output : main.cpp: In function ‘int main()’: main.cpp:31:19: error: use of deleted function ‘Student::Student(const Student&)’ Student obj = userObj; ^~~~~~~ main.cpp:19:5: note: declared here Student(const Student & obj) = delete; ^~~~~~~
Here class Student, Copy Constructor, Assignment Operator are deleted, so if we call deleted function we will get compilation error.
Deleting member functions to prevent data loss conversions :
We if the Student constructor accepts studRoll
as int, we can still call it by double & char too but it is a invalid conversions. So we can prevent it, by using delete
keyword and declaring them as deleted.
It will throw a compilation error as Student object with double and char will be deleted.
#include <iostream> #include <string> class Student { int sroll; std::string sname; public: Student(int studRoll, std::string studName) : sroll(studRoll), sname(studName) {} // To delete a constructor that accepts a double as roll Student(double studRoll, std::string studName) = delete ; // To delete a constructor that accepts a double as roll Student(char studRoll, std::string studName) = delete ; // to delete Copy Constructor Student(const Student & obj) = delete; // to delete Assignment operator Student & operator = (const Student & obj) = delete; void display() { std::cout<<sroll << " ::: "<<sname<<std::endl; } }; int main() { Student obj1(5.57, "Rick"); Student obj2('z', "Satya"); return 0; }
Output : main.cpp:35:30: error: use of deleted function ‘Student::Student(double, std::string)’ Student obj1(5.57, "Rick"); ^ main.cpp:19:1: note: declared here Student(double studRoll, std::string studName) = delete ; ^~~~~~~ main.cpp:37:30: error: use of deleted function ‘Student::Student(char, std::string)’ Student obj2('z', "Satya"); ^ main.cpp:21:1: note: declared here Student(char studRoll, std::string studName) = delete ; ^~~~~~~
Restrict Object creation on Heap by deleting new operator for class :
By deleting new operator of class Student, when we will try to create Student Object on heap using new we will get compilation.
#include <iostream> #include <string> class Student { int sroll; std::string sname; public: Student(int studRoll, std::string studName) : sroll(studRoll), sname(studName) {} // to prevent object creation on heap deleting the new function void * operator new (size_t) = delete; }; int main(){ Student * ptr = new Student(21, "Rick"); }
Output : main.cpp: In function ‘int main()’: main.cpp:23:43: error: use of deleted function ‘static void* Student::operator new(size_t)’ Student * ptr = new Student(1, "Riti"); ^ main.cpp:19:12: note: declared here void * operator new (size_t) = delete; ^~~~~~~~
Delete specific template specialization :
We can also restrict some certain specializations of template classes or functions using delete keyword.
#include <iostream> #include <string> template <typename T> class ComplexNumber { T x; T y; public: ComplexNumber(T a, T b) : x(a) , y(b) {} void display() { std::cout<<x << " + i"<<y<<std::endl; } // to deleted template specialisation ComplexNumber(char a, char b) = delete; // to deleted template specialisation ComplexNumber(double a, double b) = delete; }; int main(){ ComplexNumber<int> obj1(1,2); ComplexNumber<double> obj2(1.0,2.0); ComplexNumber<char> obj3('1' , '2'); return 0; }
Output : main.cpp:27:5: error: ‘ComplexNumber::ComplexNumber(double, double) [with T = double]’ cannot be overloaded ComplexNumber(double a, double b) = delete; ^~~~~~~~~~~~~ main.cpp:18:5: error: with ‘ComplexNumber::ComplexNumber(T, T) [with T = double]’ ComplexNumber(T a, T b) : x(a) , y(b) ^~~~~~~~~~~~~ main.cpp: In instantiation of ‘class ComplexNumber<char>’: <span class="error_line" onclick="ide.gotoLine('main.cpp',32)">main.cpp:32:25</span>: required from here main.cpp:25:5: error: ‘ComplexNumber::ComplexNumber(char, char) [with T = char]’ cannot be overloaded ComplexNumber(char a, char b) = delete; ^~~~~~~~~~~~~ main.cpp:18:5: error: with ‘ComplexNumber::ComplexNumber(T, T) [with T = char]’ ComplexNumber(T a, T b) : x(a) , y(b) ^~~~~~~~~~~~~
Difference between deleted function and private functions :
By declaring function as private we restrict its calling, but making function deleted as many benefits like:
- By deleting function with deleted keyword, the deleted functions can’t be called by other member functions, but private member functions can be even called from other member functions.
- If compiler finds a function is deleted then it will not lookup for other matching functions as Deleted function exist in lookups which will prevent unnecessary bugs and data loss.