In general the hardest and most valuable thing you can learn is to "listen to the code" (to sound all spiritual and woola for a second there). By that I mean programmers know when we're doing things that are sloppy, but often go headlong with it anyway. It's one of the most difficult things to just stop yourself there and then, back off and think: What are my alternatives?
More often than not the answer is just a simple refactor, to bring out some new class (a dependency) to allow for everything to keep the responsibilities in the right place. After all, feature creep is a danger to a project not only on a project level, but on a function and class level.
That's why I use TDD personally, means code has to be testable and the sloppy things tend to make code difficult to test so you get a nice early warning
Unfortunately C++ and the tools available still makes the act of refactoring more cumbersome than it is for languages like C# or Java (especially since they have incredible tools like Resharper and IntelliJ available).