Introduction:
Modern C++ has been there for quite some time. It has been almost a decade since it was first introduced; C++ 11 being the first standard modern C++. Since then, three standards have been added viz. C++14, C++17 and now C++20. Though, full backward compatibility to classical C++ a.k.a C++98/03 has been retained, for obvious reasons, modern C++ philosophy is different from that of C++98. Or rather, I would say modern C++ facilitates a programmer to express his/her ideas more profoundly. I will consider C++ as a highly philosophical language, mostly achieved through its elegant abstractions and model of execution.
C++ is a complex programming language, or one can call it a savvy-friendly programming language. Modern C++ has introduced lots of useful features, but certainly it has become more complex. But once you begin to understand the philosophy of this language, you will begin to realize the elegance of its simplicity.
The three foundation pillars of classical C++ are the ‘C’ subset, features for object-oriented programming and generic programming using templates. But modern C++, in addition to these, has introduced lot more features. Support for concurrent programming using threads and its associated features, ‘r-value’ references and ‘move’ semantics, smart pointers such as unique pointer, shared pointer and weak pointer are the major additions to modern C++. Of course, there are other additions that includes the ‘auto’ keyword, ‘decltype’, initializer_list, lambdas, constexpr, class template type/argument deduction, ‘nullptr’, enum classes, variadic templates, static_assert, ranged ‘for’ loops, ‘noexcept’ keyword, ‘default’ keyword, a dedicated ‘override’ keyword etcetera. Modern C++ has come a long way since C++ 98/03.
One does not have to necessarily understand all these modern features to start working on real projects in modern C++. But as I said, one has to at least grasp the major features of modern C++, such as ‘r-value’ reference and ‘move’ semantics, ownership management using smart-pointers and the basics of threads.
On this blog, I focus on the major philosophical aspects of modern C++. I also have detailed about classical C++ and its three main pillars: the ‘C’ subset, object orientation and generic programming using templates. The blog has a partitioned layout.
Part 1 is about the philosophy of ‘C’ – data abstraction, address abstraction, composite data types in ‘C’, and about the stacks in ‘C’ and how it is related to the execution model of ‘C’.
Part 2 and Part 3 illustrates the journey from classical to modern C++ and the major philosophical aspects in detail.
Part 2 is about philosophy of C++, how it achieves object orientation with classes, inheritance, polymorphism etc, what all are the main abstractions for object orientation, how compile-time and run-time polymorphism is achieved, object management model, object life-cycle management, constructors, destructors in detail, copy and move semantics in modern C++ etc.
Part 3 is about generic programming in C++, template functions and template classes, variadic templates, introduction to template specialization illustrating the working of smart pointers such as unique pointers and shared pointers, and finally about threads and concurrency.
Part 4 is a series on Design Patterns with modern C++. Implementation of realistic examples using patterns such as singleton, factory method, command, composite, observer, decorator, strategy, state, and bridge are detailed in this series.
Part 5 is about application of C++ that details how important data structures such as binary search tree, hash tables, custom arrays, queues, stacks etc. can be implemented in C++.
This blog does not teach you ‘C’ or ‘C++’ from scratch, and hence, is not an introductory material. This blog is for advancing your skills in modern C++ by understanding the philosophical essence of the language and understanding how it works. I hope that this blog will be helpful and will be a great online resource.
Let us see the topics that I’ve covered on this blog, chapter wise
Chapter |
Philosophy Aspects Covered |
Chapter 1 : |
The simplicity of ‘C’ and it’s power –
the art of abstracting data, Storing Integers – the magic of byte ordering
and packing them together, Storing negative numbers – adding a negative sign
‘-‘ just isn’t enough, Let us fix our perception of floating point numbers. |
Chapter 2 : |
Address abstraction underneath the arrays, Array
size – does it really matter to the compiler or to the programmer? Negative
indexes on arrays – seriously? Does it work? Function-addresses and how to
use them correctly? |
Chapter 3 : |
Introduction to composite data types,
The wonders of union: Vagaries of behavior, Same memory different
perspectives, Elegant use of unions for mitigating bit manipulation. |
Chapter 4 : |
Stacks and its mysteries, C’s execution model and
its companionship with stacks, The famous stack frames of ‘C’, Functions
returning big values, Parameter size promotion – The size-default and
integers, Variadic function and stack manipulation, The labyrinth of stack
corruption – do all roads lead to Rome or can we take another path? |
Chapter 5 : |
Introduction : The three aspects of
C++, Classes – establishing behaviors, Objects – manifestation of behaviors,
achieving uniqueness, How big an object really is ?, Code Reuse –
Inheritance, late binding and achieving polymorphism, Name mangling and how
to decrypt C++’s generated mangled naming convention, Code to base class
idiom, Static classes, Static member functions, initializing, working and
their intricacies, Making friends, putting enums to
use, introduction to operator overloading. |
Chapter 6 : |
Introduction to object management, The beauty of creation
with constructors, The horrors of wandering : Resource leakage, destructors
to the rescue, Virtual destructors and their significance, The principle of
Resource Acquisition Is Initialization (RAII), Establishing class invariants,
Making copies via copy constructors and copy assignment operators, The
dangers of shallow copy and understanding deep copy, Moving objects via move
constructors and move assignment operators, Compiler defaults, their vagaries
in copying and moving objects. |
Chapter 7 : |
Introduction to cloning idiom in C++,
Derived class objects and the copy conundrum, How to clone correctly?,
Moving objects of derived classes. |
Chapter 8 : |
Introduction to generic programming, Three stages of
template programming, Variadic templates and parameter packages, Containers
for storage, The elegance of C++ Standard Template Library; Meet the STL’s
three musketeers : containers – iterators – algorithms, Let’s write an Array
class, make it generic, and support iterators, Improvising object
construction using std::initializer_lists. |
Chapter 9 : |
Introduction to template
specialization, Selective method to teach template specialization in C++,
Use-case – Improvising our Unique_Ptr class from
chapter 8 to add Array support using template
specialization, default custom deleters using template
specialization and default template parameters. |
Chapter 10 : |
Sharing ownership via Shared Pointers and their
need, Atomics in Shared pointer. |
Chapter 11 : |
Concurrency achieved via threads –
parallel execution units, Let’s understand the subtleties :
Task, Process and Threads Learn about process abstraction, Let’s
spawn a process – what are the essential steps that every programmer must
understand, Threads and their inherent issues – race conditions and same time
access, Mutex locks and Condition Variables, Let’s guard our thread using
thread guards, How to mitigate issues with concurrent execution using C++
facilities, Mutually Exclusive Locks a.k.a
mutex locks, lock ownership and management in C++, Let’s implement a Queue,
Let’s implement a thread-safe queue – classic producer-consumer pattern |
Chapter 12 : |
Factory Method and abstracting the creation, How to implement Factory method in the modern C++ way |
Chapter 13 : Series On Design Patterns – Command Pattern |
Understanding a behavioral design pattern
with command pattern, How we implemented command in classic C++ (C++ 98) way,
How we should implement command in modern C++ way, Let us understand how GUI
elements like Menu and Menu Items work, and how a button click execute
actions? |
Chapter 14 : Observer
Pattern |
Let us observe a subject closely, how we can
improvise our Document editor application with observer pattern, Document
editor application is now 2.0 ! |
Chapter 15 : |
Composites, containers and primitives,
Document Editor Application is now version 3.0! |
Chapter 16 : |
Let us decorate objects, Inheritance misuse, Decorating
windows on screen! |
Chapter 17 : |
Let us strategize before action,
Document Editor App is now version 4.0! |
Chapter 18 : |
Playing safe with singletons – how to incorporate
singleton design pattern in multi-threaded environment, Let’s
put singleton and concurrency into action with our logger class. |
Chapter 19 : |
Delegating state manipulation using
state objects, Let us turn on a bulb! |
Chapter 20 : |
Let us bridge the abstracts and the implementation
entities, Let us turn on an incandescent bulb and
adjust its brightness, Let us make a florescent bulb as well. |
Chapter 21 : |
The simplicity of linear data
structures – revisiting our custom Array, Queue, The algorithmic efficiency
of non-linear data structures, Understanding Binary Search Tree (BST) and how
to implement one in C++, What all things to consider in deleting a node in a
BST |
Chapter 22 : |
Understanding Hash Tables, hash functions, hash
buckets, How to implement a custom Hash table that
can store integers and strings. |
Chapter 23 : Implementing A
Custom Heap |
How to implement a custom heap in C++ How to overload new and delete to make
use of custom heap |