It depends on where you stand in the development cycle, but sometimes when sketching out an algorithm, you want to make abstraction about complex blocks without implementing them right away.
def full_algo():
init_stuff()
process_stuff()
...
You know how init_stuff
will work, it's rather simple in your head but you don't really need it right away, so you declare it as an empty function. It will allow your code to compile and run without bothering about the gory details.
Another use for released applications is when using inheritance. Suppose that you have a large class that defines the behavior of platform specific code. You might end up with a logic similar to this :
init_filesystem();
access_files();
release_filesystem();
This code will work on many platforms, but some platforms might not need filesystem initialization. Then your inheritance will look like this (virtual with = 0 in C++ just means that derived classes MUST implement those methods) :
class FileSystem{
virtual void init_filesystem() = 0;
virtual void access_files() = 0;
virtual void release_filesystem() = 0;
};
Then a particular implementation of this class (interface) might do nothing for some of those methods. Alternatively, the base class could declare empty methods for init/release instead of declaring them virtual.
Finally (and shamefully), sometimes you maintain a very old application. You fear that deleting methods will break things. This happens when you have complex inheritance that is not properly understood or when you have a lot of function pointers (callbacks). You just delete code inside of them so they get called anyway without breaking anything.