Programming Language & Its Applications β C++ Constructs with Objects and Classes, NEC licence examination syllabus (Nepal Engineering Council).
A class bundles data with the code that manages it, and access specifiers decide who is allowed to touch what.
private, there is exactly one code path that can change it, so exactly one place to audit, log, and validate. Make it public and the balance can be changed from 400 places, and no one can guarantee it never goes negative. Every API you consume works this way: you call fopen and get a FILE* whose internals you cannot see, which is precisely why the C library can rewrite them without breaking your program. Search "encapsulation and the law of Demeter" once this clicks; it is the same idea pushed one step further.#include <iostream>
#include <string>
class BankAccount {
/* private: the class's INVARIANTS live here.
balance must never go negative β and because
nothing outside can touch it, that promise holds. */
std::string owner;
double balance;
int txn_count;
public:
BankAccount(const std::string &o, double initial = 0.0)
: owner(o), balance(initial > 0 ? initial : 0.0),
txn_count(0) {}
bool deposit(double amt) {
if (amt <= 0) return false; /* validation */
balance += amt; ++txn_count;
return true;
}
bool withdraw(double amt) {
/* the invariant is enforced in ONE place */
if (amt <= 0 || amt > balance) return false;
balance -= amt; ++txn_count;
return true;
}
/* read-only accessors, const-qualified */
double getBalance() const { return balance; }
int getTxnCount() const { return txn_count; }
void statement() const {
std::cout << owner << ": Rs " << balance
<< " (" << txn_count << " txns)\n";
}
};
int main() {
BankAccount acc("Ram Bahadur", 5000);
acc.statement();
std::cout << "deposit 2000 : "
<< (acc.deposit(2000) ? "ok" : "rejected") << "\n";
std::cout << "withdraw 3000 : "
<< (acc.withdraw(3000) ? "ok" : "rejected") << "\n";
std::cout << "withdraw 99999: "
<< (acc.withdraw(99999)? "ok" : "rejected") << "\n";
std::cout << "deposit -500 : "
<< (acc.deposit(-500) ? "ok" : "rejected") << "\n";
acc.statement();
/* acc.balance = 1000000;
error: 'balance' is a private member β and that
single error message is the whole value of the
private keyword. */
return 0;
}
Output:
Ram Bahadur: Rs 5000 (0 txns)
deposit 2000 : ok
withdraw 3000 : ok
withdraw 99999: rejected
deposit -500 : rejected
Ram Bahadur: Rs 4000 (2 txns)
private, the number of places that can break the invariant is the number of member functions β small, listable, reviewable. With public, it is the number of lines in the entire program that mention the object. Encapsulation converts an unbounded audit into a bounded one.
#include <iostream>
class Empty { };
class Data {
int a; /* 4 */
double b; /* 8 */
char c; /* 1 */
public:
void method1() { } /* functions are NOT */
void method2() { } /* stored per object */
static int shared; /* ONE for all objects */
};
int Data::shared = 0;
int main() {
std::cout << "sizeof(Empty) = " << sizeof(Empty)
<< " (never 0 β every object needs a "
"distinct address)\n";
std::cout << "sizeof(Data) = " << sizeof(Data)
<< " (4+8+1 = 13, padded to 24)\n";
Data d1, d2;
std::cout << "&d1 = " << &d1 << "\n&d2 = " << &d2 << "\n";
std::cout << "distinct objects, distinct storage\n";
return 0;
}
Output:
sizeof(Empty) = 1 (never 0 β every object needs a distinct address)
sizeof(Data) = 24 (4+8+1 = 13, padded to 24)
&d1 = 0x7ffd1a2b3410
&d2 = 0x7ffd1a2b3428
#include <iostream>
#include <stdexcept>
class Temperature {
double celsius;
static constexpr double ABSOLUTE_ZERO = -273.15;
/* private helper β implementation detail, not API */
static bool valid(double c) { return c >= ABSOLUTE_ZERO; }
public:
explicit Temperature(double c = 0.0) {
if (!valid(c))
throw std::out_of_range("below absolute zero");
celsius = c;
}
void setCelsius(double c) {
if (!valid(c)) return; /* one gate, always */
celsius = c;
}
void setFahrenheit(double f) {
setCelsius((f - 32) * 5.0 / 9.0); /* reuse the gate */
}
double getCelsius() const { return celsius; }
double getFahrenheit() const { return celsius * 9.0/5.0 + 32; }
double getKelvin() const { return celsius - ABSOLUTE_ZERO; }
};
int main() {
Temperature t(25.0);
std::cout << t.getCelsius() << " C = "
<< t.getFahrenheit() << " F = "
<< t.getKelvin() << " K\n";
t.setFahrenheit(98.6);
std::cout << "98.6 F -> " << t.getCelsius() << " C\n";
t.setCelsius(-500); /* silently refused */
std::cout << "after -500 attempt: " << t.getCelsius()
<< " C (unchanged)\n";
try { Temperature bad(-300); }
catch (const std::out_of_range &e) {
std::cout << "constructor threw: " << e.what() << "\n";
}
return 0;
}
Output:
25 C = 77 F = 298.15 K
98.6 F -> 37 C
after -500 attempt: 37 C (unchanged)
constructor threw: below absolute zero
getX/setX for every field has not encapsulated anything β it has just made the fields public with extra typing. The stronger design exposes operations (deposit, withdraw) rather than state (setBalance). Search "anemic domain model" and "tell don't ask principle"; both are direct critiques of getter-heavy design, and understanding them will make your project work noticeably better.class and struct in C++ β default access. The three-specifier access table including derived classes is a guaranteed question. Write a class with private data and public accessors enforcing a rule (bank account, temperature, or a date) β that is the standard program. Know that member functions and static members are not stored per object, and that an empty class has size 1.Create a free account to tick topics off, take notes as you read, watch the video lessons and get a day-by-day study plan built around your exam date.
Loadingβ¦