Traditionally, the purpose of delete keyword was only deallocation of heap memory. However, in C++11, this keyword has improved and it can now ask compiler to disable or hide any definition of a function. This article shall explain different scenarios about how to delete a function in C++11. Also, how a program uses this with polymorphic classes.
Delete a specific overload of an overloaded function
Overloaded functions means two or more functions with same name but different arguments. Such overloads can either be available in a 3rd party library or in a separate source file. The delete keyword here can ask compiler to disable access to one or more of overloads.
In the following example, if there are 2 overloads of a given function getSquareRoot( ). These functions are coming from a different file (mysqrt.cpp). The user of this library can delete one of the overload.
Following is the source file of library.
//mysqrt.cpp
#include <cmath> //for sqrt( )
using namespace std;
double getSquareRoot(double number) //Overload#1
{
return sqrt(number);
}
double getSquareRoot(int number) //Overload#2
{
return sqrt(number);
}
Now the file test.cpp wants to use the overloaded function
//test.cpp
#include <iostream> //main header
using namespace std; //for namespace
double getSquareRoot(int number)
//Overload#1 is available
double getSquareRoot(int number) = delete;
//Overload#2 is deleted
int main()
{
double sqroot1 = getSquareRoot(4.0);
double sqroot2 = getSquareRoot(4);
//calling deleted overload
return 0;
}
Invocation with integer argument (like above) will generate compiler error. This is because the integer argument overload no longer exists.
Delete a base class member function in derived class in C++ 11
Firstly, we know that the derived class inherits all the public members from base class. Therefore, a derived class object is able to call all the members in base. This is normal feature of inheritance.
However, it is possible that derived class can disable one or more of base class functions using delete. The following example illustrates this behavior.
#include <iostream>
using namespace std;
class MFBase
{
public:
void funda1()
{
cout << "funda1()" << endl;
}
void funda2()
{
cout << "funda2()" << endl;
}
};
class MFDerived : public MFBase
{
public:
void funda2() = delete;
};
int main()
{
MFDerived d1;
d1.funda1();
d1.funda2(); //Calling deleted member
return 0;
}
Output :
Without deleted statement, the same program would have run successfully
class MFDerived : public MFBase
{
//public:
//void funda2() = delete;
};
MFDerived d1;
d1.funda2(); //Not deleted member now
return 0;
}
Output:
Delete a specific template specialization
The template is also a form of polymorphism, i.e. static polymorphism.
Here, the delete is very usefull. Just like the overload and inheritance case, once of the template specialization can delete without any problems.
The following example shows how compiler can hide one specialization of template function getSquare( ) .
#include <iostream> //main header
using namespace std; //for namespace
template<typename T>
double getSquare(T rhs) //Template function
{
return rhs*rhs;
}
template<>
double getSquare(int rhs) = delete;
//Specialization with int argument
int main()
{
double sqroot1 = getSquare(4.0);
double sqroot2 = getSquare(4); //passing int value
return 0;
}
The output is: