Object-oriented programming (OOP) is the most popular programming paradigm of our times. Hugely successful languages such as Java, Python and C++ all use an OOP design. But what is OOP? 

What are the advantages of using it? And what other paradigms are out there? In this article, we’ll address all these questions and more by using examples in C++.

What Is OOP?

Computers — operating in binary — differ from the real world in a significant way. In computers, a switch is either on or off — there’s no in-between. So when we try to solve real-world problems with the help of computers, the big issue is figuring out how to encode our often messy realities using clean, discrete numbers that the computer can understand. That’s what programming paradigms are for — just ask any student of C++


The object-oriented paradigm is based on a complex data type known as the “class.” A class may have several associated methods and attributes. These are collectively referred to as the “class members.” Attributes are a class’s properties, while methods refer to functions associated with the class. For instance, let’s say we have the class “Dog.” This is how we’d write it in C++: 

class Dog {
        std::string name;
          bool drools;
        void barks() {
                std::cout << "Woof Woof\n";

Our “Dog” class has attributes, these being “name” and the Boolean value “drools” (which tells us whether we’re dealing with a drooling dog). It also comes with a member function — a method —  that we call “barks. (Let’s ignore the “public” keyword for now; we’ll get into that a little bit later.)


So where does the object fit into this paradigm? Simple: An object is an instantiation of a class. This means that while the class describes the design of an object, the object itself is a real data structure that interacts and communicates with other objects. To instantiate an object from our blueprint class called “Dog,” we declare: 

int main() {
Dog Fufu; // the code continues below

Thus, we have created a “Dog” object called “Fufu,” which already comes with all the methods and attributes that we associate with dogs. We can see that by trying to use the class method “barks()” with our object “Fufu”:

return 0;

This method call outputs the following, which shows that “Fufu” possesses the features that we defined for the “Dog” class:

Woof Woof

OOP vs. Procedural Programming

Early programming languages — such as Fortran and BASIC — all followed the procedural paradigm, meaning that they were purely imperative in nature. This is because these languages operated much more in line with the computer’s hardware. And at that level, programming a computer boils down to telling it what to do at every step in a procedural manner. 

However, when we wish to write more complex code, we find procedural programming languages to have an array of disadvantages. Coding in a language like C is tedious because you have to explicitly tell the machine which steps to go through. For the same reason, code becomes harder to read and is likely to repeat itself. Classes offer a degree of abstraction that helps the programmer take a more high-level approach and write modular code that’s cleaner and more readable. 

Why Is Object-oriented Programming Useful?

Object-oriented programming has proven to be a good model for many modern applications. Take social networks for example. Every social network is essentially made up of a handful of core elements, such as users, posts, messages, and so on. Each of these comes with a set of attributes and actions. As our network expands the number of elements grows; crucially, on the other hand, functionality stays more or less the same.

For example, a social network user may like a post, which action would be associated with a member method for the “User” class. In addition, every user has a certain friend count, which we can conceptualize as an attribute of that class. Now, when a new user joins the network, the application needs only to create an instance of the “User” class, and a new object is born, with all the behavior associated with that network’s users.


As our example demonstrates, classes introduce an entity-based model of the world. Internally, this higher-level code is still converted to an algorithmic procedure. However, it’s hidden beneath an additional layer of abstraction. Because of this property, OOP advocates often describe object-oriented languages as being closer to how things work in the real world. 


A class is not only used as a blueprint for objects, but it can also serve as a starting point for new classes. Let’s say that our dog app (for which we wrote the original “Dog” class) is doing well and getting lots of new members. We realize that different breeds of dogs show different behavior. Do we have to write a new class for each dog that comes to us? No! We can simply let each new class inherit attributes and methods from the general “Dog” class. 

class Labrador : public Dog {
        void catchBird() {
            std::cout << "Look what I've caught!\n";
int main() {
  Labrador Fufu;
  Fufu.name = "Fufu";
std::cout << "My name is " << Fufu.name << "\n";
return 0;

Calling our “main” function outputs the following:

My name is Fufu
Woof Woof
Look what I've caught!

Casting Fufu a labrador means that she is automatically also defined as a dog, with all of the associated behavior. As the example demonstrates, inheritance perfectly emulates real-world taxonomies.


Remember the “public” keyword? It points to another crucial feature of OOP languages, known as encapsulation. Encapsulation helps control the parts of an object that are accessible from the outside, basically providing every object with a mini API. C++ uses the access specifiers “public,” “private” and “protected” to determine which class members are available to the outside world.

Typically, data used only by the class itself is made private. It’s not accessible from the outside and remains hidden from the user. In C++, class members are private by default.

If we do want to access an object’s features, we need to explicitly declare them as “public.” In the case of our “Dog” class, we wanted our attributes and methods to be public. Let’s say we want to change the animal’s name, and to print the output of our functions “barks” and “catchBird.” If you change the access specifier from the public to private in the code example, you’ll see that private features are no longer available.

The third access specifier is called “protected.” It behaves similarly to the “private” keyword, protecting class members from access from the outside. However, its functions and variables can be accessed by child classes (born through inheritance). 

How Object-oriented Is C++?

Did you know that the first version of C++ was called “C with classes”? That’s because C++’s creator, Bjarne Stroustrup, deliberately designed it to combine C’s computational power with the ease of use provided by classes. The result was a notoriously complex programming language. The reason why many people find C++  hard to learn is precisely because it’s multiparadigmatic.

In addition to the object-oriented programming style that we outlined above, it’s also possible to write C++ code that’s procedural and looks a lot like it was written in C. What’s more, ever since the 2011 release, C++ has also supported functional programming (FP). FP is a purely declarative programming paradigm that operates at an even higher level of abstraction and is increasingly touted as the future of programming.

Start Learning C++ Today

C++’s versatility when it comes to programming paradigms is what makes it so powerful and well-loved. However, this adaptability is also why many programmers find C++ harder to learn than other mainstream programming languages. 

With that said, there has never been a better time to start learning C++. To get started, check out “C++ Nanodegree,” our interactive, expert-taught course that includes comments and tips from the father of C++ himself.

Start Learning