Skip to content
Educora
Intermediate20 min7 / 10

Classes and objects

Create your own types: class members, methods, constructors and destructors, and encapsulation with `public` and `private`.

Check yourself
In this lesson you will learn
  • Explain the ideas of a class and an object
  • Write a class with member variables and methods
  • Write constructors with an initializer list, and a destructor
  • Protect data with public and private

A game has hundreds of characters: each has a name, health and a level, and each can move and attack. Keeping all that in separate variables and functions quickly turns into a tangle. C++ lets you create your own type — a class. A class bundles data together with the functions that work on it.

Class and object

Definition
Class and object

A class is the blueprint for a new type: it describes what data (member variables) and what functions (methods) its objects will have. An object is a concrete instance created from that class — just as x is a variable of type int when you write int x;.

C++
#include <iostream>
#include <string>

class Student {
public:
    std::string name;
    int grade = 0;

    void introduce() const {
        std::cout << name << " is in grade " << grade << '\n';
    }
};

int main() {
    Student a;
    a.name = "Aysel";
    a.grade = 8;

    Student m;
    m.name = "Murad";
    m.grade = 9;

    a.introduce();
    m.introduce();
    return 0;
}
Expected output
Aysel is in grade 8
Murad is in grade 9
  • Members are reached with a dot: a.name, a.introduce().
  • Every object has its own data: a and m come from the same class but have different names and grades.
  • const after a method means it does not change the object; the compiler checks this.

Constructors and the destructor

A constructor is a special method that is called automatically when an object is created. It has the same name as the class and no return type. Like ordinary functions, constructors can be overloaded. Members are best given their values in the initializer list — after a colon, before the body: : width_(w), height_(h).

C++
#include <iostream>

class Rectangle {
public:
    Rectangle() : width_(1), height_(1) {}
    Rectangle(int w, int h) : width_(w), height_(h) {}

    int area() const { return width_ * height_; }
    int perimeter() const { return 2 * (width_ + height_); }

private:
    int width_;
    int height_;
};

int main() {
    Rectangle tile;
    Rectangle room(4, 3);
    std::cout << "Tile area: " << tile.area() << '\n';
    std::cout << "Room area: " << room.area() << '\n';
    std::cout << "Room perimeter: " << room.perimeter() << '\n';
    return 0;
}
Expected output
Tile area: 1
Room area: 12
Room perimeter: 14

A destructor is called when an object is destroyed: its name starts with ~ (~Logger). A local object is destroyed when it leaves its scope — its own pair of curly braces. The RAII principle from the previous lesson is built on exactly this: a resource is acquired in the constructor and released in the destructor.

C++
#include <iostream>
#include <string>

class Logger {
public:
    Logger(const std::string& name) : name_(name) {
        std::cout << "Start " << name_ << '\n';
    }
    ~Logger() {
        std::cout << "End " << name_ << '\n';
    }

private:
    std::string name_;
};

int main() {
    Logger a("A");
    {
        Logger b("B");
    }
    std::cout << "Main done\n";
    return 0;
}
Expected output
Start A
Start B
End B
Main done
End A
b is destroyed when the inner block ends, and a when main ends.

public, private and encapsulation

If any code could change a bank account's balance directly, someone could set it to a negative value by mistake. Encapsulation hides the data and allows access only through methods that check the input. This is what access specifiers are for: public members are visible everywhere, while private members are visible only to the class's own methods.

C++
#include <iostream>

class BankAccount {
public:
    BankAccount(int balance) : balance_(balance) {}

    void deposit(int amount) {
        if (amount > 0) {
            balance_ += amount;
        }
    }
    bool withdraw(int amount) {
        if (amount <= 0 || amount > balance_) {
            return false;
        }
        balance_ -= amount;
        return true;
    }
    int balance() const { return balance_; }

private:
    int balance_;
};

int main() {
    BankAccount acc(100);
    acc.deposit(50);
    std::cout << std::boolalpha << acc.withdraw(500) << '\n';
    std::cout << acc.withdraw(30) << '\n';
    std::cout << "Balance: " << acc.balance() << " AZN\n";
    // acc.balance_ = 1000000;  // error: balance_ is private
    return 0;
}
Expected output
false
true
Balance: 120 AZN
Withdrawing 500 from 150 manats failed, but 30 succeeded: 150 − 30 = 120.
SpecifierWho can access it
publicany code
privateonly the class's own methods
protectedthe class's own methods and derived classes (next lesson)

Key points

  • A class is the blueprint of a new type; an object is a concrete instance of it.
  • Members are reached with a dot; a const method does not change the object.
  • The constructor runs automatically when an object is created, the destructor (~Name) when it is destroyed.
  • The initializer list is the best place to give members their values.
  • private hides data and public methods give controlled access to it — that is encapsulation.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
What is the difference between a class and an object?