Classes & Objects: Encapsulation Fundamentals
ক্লাস ও অবজেক্ট — ক্যাপসুলেশন
1. The Class — A Custom Type
A class bundles state (data members) with behavior (member functions). Each instance of the class is an object with its own copy of the data.
#include <iostream>
#include <string>
class Person {
private:
std::string name_;
int age_;
public:
Person(std::string name, int age)
: name_(std::move(name)), age_(age) {}
void greet() const {
std::cout << "Hi, I'm " << name_ << ", " << age_ << "\n";
}
void birthday() { ++age_; }
int age() const { return age_; }
};
int main() {
Person sara{"Sara", 21};
sara.greet();
sara.birthday();
std::cout << "Now: " << sara.age() << "\n";
}
2. Access Specifiers
| Specifier | Visible to |
|---|---|
private | Only member functions of the class |
protected | Class and its subclasses |
public | Everyone |
private. Expose only the operations the class needs. This protects invariants.
3. Member vs Non-member Functions
Methods on the class can read/write its private data. Free (non-member) functions can only use the public interface. Free functions are often a better choice when the operation doesn't need privileged access.
4. The this Pointer
Inside a non-static member function, this is a pointer to the current object.
class Counter {
int n_ = 0;
public:
Counter& increment() { ++this->n_; return *this; }
int value() const { return n_; }
};
// Allows: c.increment().increment().increment();
5. const Member Functions
A function marked const after the parameter list cannot modify the object. You can
call const methods on const objects.
const. Otherwise const users can't call it.
6. Class Invariants
An invariant is a condition that must always be true between calls to public methods. The class enforces it:
class Fraction {
int num_, denom_;
public:
// Invariant: denom_ != 0
Fraction(int n, int d) : num_(n), denom_(d) {
if (d == 0) throw std::invalid_argument{"zero denom"};
}
double value() const { return double(num_) / denom_; }
};
7. Practice Problems
- Define class
Point2Dwith x, y and a methoddistanceTo.✨ Show Answer
class Point2D { double x_, y_; public: Point2D(double x, double y) : x_(x), y_(y) {} double distanceTo(const Point2D& o) const { double dx = x_-o.x_, dy = y_-o.y_; return std::sqrt(dx*dx + dy*dy); } }; - Why make data members private?
✨ Show Answer
To protect invariants. If users can write directly to internals, the class can't ensure validity (e.g. denominator never 0). Public interface is the contract; private is implementation.
- Define a
BankAccountwith a non-negative balance.✨ Show Answer
class BankAccount { double balance_ = 0; public: void deposit(double a) { if (a > 0) balance_ += a; } bool withdraw(double a) { if (a > 0 && a <= balance_) { balance_ -= a; return true; } return false; } double balance() const { return balance_; } }; - Why mark
balance()as const?✨ Show Answer
It only reads. Marking it const allows it to be called on a const BankAccount.
- What's the difference between
structandclass?✨ Show Answer
Default access.
structdefaults to public;classdefaults to private. Convention:structfor data bags,classfor encapsulated objects. - Define a member function that returns
*thisfor chaining.✨ Show Answer
See section 4 —
Counter& increment() { ++n_; return *this; }. - What is an aggregate?
✨ Show Answer
A class without user-declared constructors, virtual functions, or private/protected non-static data. You can use brace-init with members directly:
Point{1, 2}. - Add a
staticmember counting all Person instances.✨ Show Answer
class Person { static int count_; public: Person() { ++count_; } ~Person() { --count_; } static int alive() { return count_; } }; int Person::count_ = 0; - Define
operator==as default for a struct (C++20).✨ Show Answer
struct Point { int x, y; bool operator==(const Point&) const = default; }; - What's a getter? A setter?
✨ Show Answer
Getter:
constmethod returning the value of a member. Setter: method that assigns to a member, possibly with validation. Don't add them blindly — only when truly needed by clients. - Why is C++ method dispatch usually compile-time?
✨ Show Answer
By default, member calls are statically bound. Only
virtualfunctions are dispatched at runtime via vtable. - Define a class with a private helper method.
✨ Show Answer
class X { int compute() const { return 42; } // private helper public: int publicAPI() const { return compute() + 1; } }; - What does
Person p;do — calls which constructor?✨ Show Answer
Default constructor. If you didn't write one, the compiler tries to generate it; if a member is uninitializable (e.g. a const member with no default), it fails.
- Define a class member with default value
= 0.✨ Show Answer
class X { int n = 0; }; // in-class member init - Use a member init list in a constructor.
✨ Show Answer
Person(std::string n, int a) : name_(std::move(n)), age_(a) {}Initializes members directly — more efficient than assigning in the body.
- Why prefer member init list over body assignment?
✨ Show Answer
The body runs after all members are default-constructed. Init list constructs members directly with the given args — saving a default construction + assignment. For const/reference members, init list is required.
Summary
A class bundles data and behavior. Make data private; expose a clean public interface.
Mark methods const when they don't modify state. Use member init list for
efficient construction. The class enforces invariants the language alone can't.