Classes are to be preferred if you may want to subtype them and their behavior. Example for your logging functionality. You might a logging class to log to a file, rotating the files when they get to a certain size, and another one to send log messages to a remote system via TCP/IP or some sort of middleware. Their functionality is basically the same, but how they do what they do is quite different, so some virtual functions for the actual logging would be appropriate, especially if you had a virtual base class as effectively an interface class. That way, you could pass a pointer to that base class to a function and it could log stuff without needing to know what kind of logging class you are using. This sort of operator overloading is extremely useful in order to work with what we call abstractions, or in more current parlance, patterns.
Function libraries are very useful when what you are doing is discrete, such as TCP/IP socket handling, and not likely to be used to derive new behaviors.