No history yet

Introduction to C++ Classes

Blueprints for Objects

In programming, we often need to model real-world things. Think about a car, a user account, or a bank account. These aren't simple numbers or strings; they're complex entities with their own data and behaviors.

C++ gives us a powerful tool to create these models: the class. A class is like a blueprint. A blueprint for a house isn't a house itself, but it contains all the details needed to build one. Similarly, a class defines the properties and actions for a new type of data, but it isn't the data itself. Once you have the blueprint, you can create actual objects from it, just like building multiple houses from the same blueprint.

A class in C++ is a user-defined data type that serves as a blueprint or template for creating objects.

Let's start with the basic syntax. We use the class keyword, give our new type a name, and enclose its definition in curly braces, followed by a semicolon.

class Car {
// Member variables and functions go here
};

class UserAccount {
// Member variables and functions go here
};

This code doesn't create any cars or user accounts. It just defines the templates for what a Car and a UserAccount will be.

Adding Members

A class bundles two things together: data and the functions that operate on that data. The data elements are called member variables (or attributes), and the functions are called member functions (or methods). This bundling is a key principle of object-oriented programming.

encapsulation

noun

The bundling of data and the methods that operate on that data into a single unit, or class.

For our Car blueprint, the member variables might include its color, make, and current speed. The member functions would be the actions it can perform, like accelerating or braking.

class Car {
public:
  // Member functions
  void accelerate() {
    speed += 5; // Increase speed by 5 mph
  }

  void brake() {
    speed -= 5; // Decrease speed by 5 mph
  }

private:
  // Member variables
  std::string color;
  std::string make;
  int speed = 0; // Starts at 0 mph
};

You'll notice the public and private keywords. These are called access specifiers, and they control how different parts of your program can interact with the class members.

Controlling Access

Access specifiers are crucial for encapsulation. They let us hide the internal complexity of a class and expose only what's necessary. Think of a real car: you interact with it using a steering wheel, pedals, and a gear stick. You don't interact directly with the engine's fuel injectors or spark plugs. That complex machinery is hidden away.

In C++, we achieve this with public, private, and protected.

SpecifierAccessibility
publicMembers are accessible from outside the class.
privateMembers cannot be accessed from outside the class. Only the class's own member functions can access them.
protectedSimilar to private, but allows access by derived classes (a topic for later).

By making speed private, we prevent code outside the Car class from setting it to an unrealistic value, like a negative number. The only way to change the speed is through the public accelerate and brake functions, which control how the speed changes. This is the essence of data protection.

This separation of interface (public) from implementation (private) is another key concept.

abstraction

noun

The concept of hiding complex implementation details and showing only the essential features of the object.

Construction and Destruction

When we create an object from a class blueprint, we often want to initialize its member variables. For example, when a Car object is created, we might want to set its color and make right away. This is done with a special member function called a constructor.

A constructor has the same name as the class and has no return type. It's called automatically when an object is created.

#include <iostream>
#include <string>

class Car {
public:
  // Constructor
  Car(std::string c, std::string m) {
    color = c;
    make = m;
    speed = 0;
    std::cout << "A " << color << " " << make << " was created." << std::endl;
  }

private:
  std::string color;
  std::string make;
  int speed;
};

Now, to create a Car object, we must provide a color and make:

Car myCar("Blue", "Toyota");

This line of code calls the constructor, creating a Car object named myCar and initializing its variables. It will print "A Blue Toyota was created."

The opposite of a constructor is a destructor. It's another special member function that runs automatically when an object is destroyed (for instance, when it goes out of scope). A destructor's name is the class name preceded by a tilde (~), and it takes no arguments.

Destructors are essential for cleanup, like releasing memory or closing files that the object was using.

class Car {
public:
  // Constructor (same as before)
  Car(std::string c, std::string m) {
    color = c;
    make = m;
    // ...
  }

  // Destructor
  ~Car() {
    std::cout << "The " << color << " " << make << " was destroyed." << std::endl;
  }

private:
  std::string color;
  std::string make;
  // ...
};

When the myCar object from our previous example is no longer needed, its destructor will be called automatically, printing a message that it was destroyed.

Quiz Questions 1/6

In C++, what is a class best described as?

Quiz Questions 2/6

Which access specifier should be used for member variables to enforce encapsulation and prevent direct modification from outside the class?

Classes are the cornerstone of object-oriented programming in C++. They allow you to create complex, reusable, and well-organized code by modeling the world in a more intuitive way.