Learning C++ is not something you do in a few weeks or by reading a single book. It’s a long process — and it shouldn’t be boring.
The biggest advantage of learning a programming language is that you can practice it right away. You can build things with your own hands, and my advice is to start doing that as early as possible.
Becoming proficient in C++ requires not only theoretical knowledge, but also practical skill. First, you learn a concept. Then, you apply it in practice. Only after that do you start to understand its trade-offs.
In this article, I’ll outline the most important areas to focus on and the timeline I would follow if I were starting today.
Why learning C++ should start with building
Start building early.
Software development is exciting. I still remember the feeling when I solved one of my first C++ tasks. I couldn’t sleep until I finished the algorithm for a simple calculator. That excitement is one of the reasons I still enjoy software development today.
C++ development is not only about the language itself. Even junior positions often require at least basic knowledge of build systems and testing frameworks. So instead of trying to learn C++ in depth from the very beginning, I would first focus on the basics of:
- C++
- STL
- CMake
- GTest
- code design
With that foundation, you can already build and test a simple C++ application. That will reinforce your theoretical knowledge with practical experience. And I strongly recommend starting as early as possible.
Create a simple project — for example, a calculator. Keep it simple at first, and then add complexity as you learn more. A possible evolution could look like this:
- start with a single
.cppfile and a few classes after learning the STL basics, - split it into multiple files after learning CMake,
- add tests once you start learning GTest,
- revisit the overall design later, once you study design principles and templates.
A practical project is one of the best ways not only to learn language features, but also to understand how and when to use them.
Stage 1: C++ fundamentals
To be a professional you need deep C++ understanding including meta-programming, reflexion and other things. But for beginning consider only basic stuff:
- loops and conditions,
- functions,
- local and global variables,
- pointers and references,
- memory management,
- classes, inheritance and polymorphism,
- static class functions and members,
- constness,
- copy and move semantic,
- RAII.
Solid understanding this topics helps writing safe C++ code. Even as a senior C++ developer I use the usually in my daily work.
I would prpostpone
At this point I think wouldn’t do a deepndive into the templates or multithreading programming. For me it’s better to postpone that topics till the mement you have knowledge about the whole c++ toolchain.
Stage 2: STL
STL is a part of the language standard and supplied usually with the compiler. Most of the C++ code use it. And it’s not a taste thng, but application of an appropriate algorithm or container makes the code safer and easier to read. So it’s important to learn STL and namely:
- containers,
- algorithms,
- ranges and views,
- smart pointers,
- optional and expected.
You don’t know by hart all C++ algorithms or be able to name each member function, because using the documentation is totally fine for that purpose and I use it always.
Instead build an understanding:
- When to use which container,
- How to replace for-loop with an appropriate algorithm,
- Difference between std::expected and std:: optional
- Which and when apply smart pointers.
Because that information helps to make a proper description faster and the rest you can get from the documentation.
I would prpostpone
Consider not trying to learn by hart each single algorithm or container members. Also I would avoid learning multithreading primitives, castom allocators or parts of the library responsible fro meta-programming. The STL library is quite big you can learn small part of it and then continue futher as a followup topics.
Practical experience
To train STL and overall C++ you can apply things like Leetcode. Consider the easiest tasks.
As told before create a simple application: calculator or text parser. Put several classes into a single C++ file and just compile it to an console application.
One class is for handling input from the user and printing back the result. The other is for doing the calculation itself.
Stage 3: CMake
You can write C++ code and build a small application from a single source file. But real-world projects usually consist of multiple libraries and executables. To build and manage such projects, you need a build system — and the most common choice in modern C++ is CMake.
Right after the STL, I would learn the following CMake basics:
- the overall structure of a CMake project,
- how to create an executable and a library,
- what a target is,
- how to specify include directories, link libraries, and compile definitions for a target,
- how target properties propagate,
- how to use external libraries in your project.
In production code, you may eventually need more than that. But these topics are the fundamentals you need almost everywhere. Once you understand them, you can already build a real application — and that is exactly what I would recommend doing.
What I would postpone
At this stage, I would not do a deep dive into the CMake language itself. Yes, it is useful to know about functions, macros, loops, or how to integrate tools like clang-tidy or Doxygen, but I would treat those as follow-up topics.
Practical experience
Once you understand how to build a multi-file project, update your own project accordingly. In the case of the calculator, each class should get its own header and .cpp file, and CMake should be used to build them into an executable.
An even better approach is to move the calculator logic into a static library, while the executable contains only the main() function and uses the library functionality.
Want more practical C++ breakdowns like this?
I write a monthly newsletter, From complexity to essence in C++, where I explain modern C++, CMake, and real-world engineering trade-offs in a simple way.
As a bonus, new subscribers get a free guide: What You Should Know About Targets in Modern CMake.
Subscribe here: Modern CMake becomes simple once you understand how targets work
Stage 4: Testing
Till this moment you should be capable to build a C++ application and do some manual tests to ensure that it works. The production code relies on the automated tests first of all in the CI/CD pipeline.
And when you have a project it’s a good time to add some unit-tests to it. And here I advise to consider following topics:
- How to include GTest into CMake configuration,
- How to create test cases,
- When to use
TESTandTEST_Fto use, - Which assertions GTest offers,
- How to apply mocks,
- How to inject dependencies.
I advise GTest because it’s the one of the most prominent testing frameworks. You can use any other, but the overall logic in others the similar.
I would prpostpone
GTest ofers quite a lot of options: castom matchers or data-driven tests. Yet they are usefull but I would consider them as topics for the followup learning.
Practical experience
By learning unit-tests add them into your project. If you have already split into a library and executable – it’s easier. Otherwise that split is required.
Stage 5: Code design
By this point, you already have enough knowledge to build and test a C++ application. You may also start noticing that some classes are bigger than they should be, while others try to do too many things at once. That is exactly the moment when it makes sense to study code design.
There are two main areas I would focus on:
- design principles (for example, SOLID),
- design patterns.
Neither of them will tell you exactly what to do in every situation. Instead, they help you reason about how to split a codebase into smaller logical parts that work together to solve a larger problem. This leads to code that is easier to test, easier to change, and usually safer.
Practical experience
Go back to your project and look at the classes you have already written.
Can any of them be split into smaller, more focused ones?
Are there classes that mix input handling, business logic, and output formatting?
That is usually a good sign that design improvements are possible.
What comes next?
Once you reach this point, you already have a strong foundation: you can write C++ code, build it with CMake, test it, and improve its structure.
From there, the next step is not to rush into every advanced topic at once, but to keep learning gradually while continuing to build real projects.
There is still a lot to explore:
- C++ multithreading,
- template metaprogramming,
- the CMake language itself,
- advanced testing topics such as parameterized tests and custom matchers,
- performance, debugging, and tooling.
The biggest mistake developers make is not that they do not know everything yet.
It is that they stop learning once they become “good enough.”
C++ is not a language you finish learning. It is a language you grow into.
Start with the fundamentals, build something real, and let each next topic come from practice.
That is the path I would choose today — and it is still the path I follow now.
If you want to go one step further and see how C++, CMake, project structure, and practical engineering fit together in a real project, take a look at my book:
No More Helloworlds — Build a Real C++ App
Learn more: https://sqglobe.com/no-more-helloworlds-build-a-real-c-app/