Deleted Class Methods

One of the new features in C++0x is a declaration syntax allowing you to remove methods from a class entirely. While this may sound rather strange at first blush, it does have some interesting usages that will make your code cleaner and more readable.

A deleted function is one whose declaration is explicitly removed from a class. This can be especially useful when you want to explicit remove some functionality that would otherwise be implicitly defined for you. For instance, in C++03, if you want to define a class that is non-copyable, you would do it by declaring a private copy constructor, and private operator= overload.

class noncopyable {
private:
	noncopyable( const noncopyable& );
	noncopyable& operator=( const noncopyable& );
};

By being explicit with those two function declarations, you are ensuring that the user cannot create a copy of the object. While this is effective, it is also a bit dangerous in that you can still create copies of noncopyable from within the noncopyable class itself (since it has access to its private members). Granted, by not defining those functions (only declaring them), you will wind up with linker errors. However, linker errors are rarely ever intuitive!

Now, with C++0x, you can explicitly delete those functions, thereby ensuring the compiler does not generate a default implementation of them. This will mean that you get a more sane compile error, regardless of where the attempted copy happens. It also makes your intentions more clear — someone maintaining your code isn’t left wondering “did they just forget to implement these functions?”

class noncopyable {
public:
	noncopyable( const noncopyable& ) = delete;
	noncopyable& operator=( const noncopyable& ) = delete;
};

Another example of when it might make sense to use deleted functions is if you wish to ensure a class is only ever allocated on the stack (instead of on the heap). You can delete the default operator new functions from the class:

class stack_only {
public:
	void *operator new( std::size_t ) = delete;
	void *operator new[]( std::size_t ) = delete;
};

The last handy purpose to deleting functions I’d like to cover has to do with limiting implicit conversions. Every once in a while, you’ll design an API where you want to ensure that implicit conversions do not occur. For instance, let’s say you’re writing an instance method for integer sqrt for some strange reason. This function only makes sense on unsigned values — a signed sqrt would result in an imaginary number. So you can simply remove the signed versions of your call:

double isqrt( unsigned int val );
double isqrt( int ) = delete;

tl;dr: you can explicitly remove access to certain method signatures by specify = delete at the end of the declaration.

This entry was posted in C/C++ and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.