In my youth there was a lot of support for object oriented programming. It was generally agreed that we had a software productivity problem: it was too hard to write programs. The solution was supposedly to adopt object oriented programming techniques. This was expressed in its purest form in Smalltalk, and was brought to the masses in Object Pascal (later Delphi) and C++, followed by Java.
Object oriented programming had a few different ideas, all of which centered around the notion of separating data into relatively small and independent units. Methods are defined independently of specific data, and a given method may be applied to different data units. Data units are grouped by sets of methods, and the method sets can be put into inheritance and abstraction hierarchies.
Object oriented approaches were greatly oversold, and it became clear over time that while they did have many good ideas, they were not the solution to the problems of programming. One of the problems of the object oriented approach is that it encourages you to focus on the relationship between sets of methods that apply to data, rather than focusing on the structure of the data itself. In C++ or Java terms, it’s easy to spend more time thinking about the inheritance relationships between classes than about the individual objects.
Over time, C++ shifted toward a somewhat different style of programming found in the Standard Template Library. This style is based on templates, and focuses on containers and algorithms. I’ve seen people advocate this approach to the point of saying that a good program should have no non-abstract loops: that everything should be done via an appropriate algorithm.
The issue I find with these approaches in practice is that they tend to lead to too much abstraction. Fundamentally all programs deal with data. The goal of a program is to manipulate the data in some way. The goal of abstraction and class inheritance is to permit you to write less code. The goal of data encapsulation is to make your program more maintainable over time. Abstraction beyond those points may make your program better by some artificial index, but it is not really helping you get things done.
If you find yourself asking yourself whether to introduce a new level in your class hierarchy, or you find yourself writing a new template which will only be instantiated once, then you may be falling victim to the abstraction penalty. Shake it off and return to focusing on what your program really needs to do.