Programming Language & Its Applications β C++ Constructs with Objects and Classes, NEC licence examination syllabus (Nepal Engineering Council).
One copy shared by every object of the class β class-level state, not object-level.
static is the same keyword doing the same job; Python uses class attributes. And the singleton pattern, which you will meet in the software-engineering paper, is built entirely from a private constructor plus a static instance. Search "singleton pattern is an anti-pattern" after this page β it is one of the most productive arguments in software design, and understanding both sides makes you better at judging any global state.#include <iostream>
class Widget {
static int liveCount; /* currently alive */
static int totalCreated; /* ever created */
int id;
public:
Widget() : id(++totalCreated) {
++liveCount;
std::cout << " create #" << id
<< " live=" << liveCount << "\n";
}
~Widget() {
--liveCount;
std::cout << " destroy #" << id
<< " live=" << liveCount << "\n";
}
/* static function: no object needed to call it */
static int getLive() { return liveCount; }
static int getTotal() { return totalCreated; }
int getId() const { return id; }
};
/* the mandatory definitions */
int Widget::liveCount = 0;
int Widget::totalCreated = 0;
int main() {
std::cout << "before any object: live="
<< Widget::getLive() << "\n";
Widget a;
{
Widget b, c;
std::cout << "inside block: live="
<< Widget::getLive() << "\n";
} /* c and b destroyed */
Widget d;
std::cout << "live=" << Widget::getLive()
<< " total ever created=" << Widget::getTotal()
<< "\n";
std::cout << "sizeof(Widget) = " << sizeof(Widget)
<< " (only the int id β statics are elsewhere)\n";
return 0;
}
Output:
before any object: live=0
create #1 live=1
create #2 live=2
create #3 live=3
inside block: live=3
destroy #3 live=2
destroy #2 live=1
create #4 live=2
live=2 total ever created=4
sizeof(Widget) = 4 (only the int id β statics are elsewhere)
#include <iostream>
#include <string>
class Temperature {
double celsius;
/* private ctor: objects only via the factories */
explicit Temperature(double c) : celsius(c) {}
public:
/* FACTORY functions β named constructors.
Two "constructors from a double" are impossible as
overloads, but as named statics they are clear. */
static Temperature fromCelsius(double c) {
return Temperature(c);
}
static Temperature fromFahrenheit(double f) {
return Temperature((f - 32) * 5.0 / 9.0);
}
static Temperature fromKelvin(double k) {
return Temperature(k - 273.15);
}
/* pure utility β needs no object at all */
static double c2f(double c) { return c * 9.0/5.0 + 32; }
double get() const { return celsius; }
};
class IdGenerator {
static int next;
public:
static int generate() { return next++; }
static void reset() { next = 1; }
};
int IdGenerator::next = 1;
int main() {
auto a = Temperature::fromCelsius(100);
auto b = Temperature::fromFahrenheit(98.6);
auto c = Temperature::fromKelvin(300);
std::cout << "100 C = " << a.get() << " C\n";
std::cout << "98.6 F = " << b.get() << " C\n";
std::cout << "300 K = " << c.get() << " C\n";
std::cout << "c2f(37) = " << Temperature::c2f(37)
<< " F (no object created)\n";
std::cout << "ids: ";
for (int i = 0; i < 5; i++)
std::cout << IdGenerator::generate() << " ";
IdGenerator::reset();
std::cout << "| after reset: "
<< IdGenerator::generate() << "\n";
return 0;
}
Output:
100 C = 100 C
98.6 F = 37 C
300 K = 26.85 C
c2f(37) = 98.6 F (no object created)
ids: 1 2 3 4 5 | after reset: 1
private and exposing only static factories is a genuine design tool, not a trick. It guarantees every object goes through code you control, which means you can validate, cache, return a subclass, or return an existing instance instead of a new one β none of which a plain constructor can do, because a constructor must always produce a fresh object.
#include <iostream>
#include <string>
class Account {
static double interestRate; /* bank-wide */
static int accountCount;
static double totalDeposits;
std::string owner;
double balance;
int accNo;
public:
Account(const std::string &o, double b)
: owner(o), balance(b) {
accNo = ++accountCount;
totalDeposits += b;
}
void deposit(double amt) {
if (amt <= 0) return;
balance += amt;
totalDeposits += amt; /* shared total updates */
}
double yearEndBalance() const {
return balance * (1 + interestRate / 100.0);
}
/* one call changes the rate for EVERY account */
static void setRate(double r) { interestRate = r; }
static double getRate() { return interestRate; }
static int count() { return accountCount; }
static double bankTotal() { return totalDeposits; }
void show() const {
std::cout << " #" << accNo << " " << owner
<< ": Rs " << balance
<< " -> year end Rs " << yearEndBalance()
<< "\n";
}
};
double Account::interestRate = 5.0;
int Account::accountCount = 0;
double Account::totalDeposits = 0.0;
int main() {
Account a("Ram", 10000);
Account b("Sita", 20000);
Account c("Hari", 50000);
b.deposit(5000);
std::cout << "accounts=" << Account::count()
<< " bank total=Rs " << Account::bankTotal()
<< " rate=" << Account::getRate() << "%\n";
a.show(); b.show(); c.show();
std::cout << "\nRBI raises the rate to 8.5%:\n";
Account::setRate(8.5);
a.show(); b.show(); c.show();
return 0;
}
Output:
accounts=3 bank total=Rs 85000 rate=5%
#1 Ram: Rs 10000 -> year end Rs 10500
#2 Sita: Rs 25000 -> year end Rs 26250
#3 Hari: Rs 50000 -> year end Rs 52500
RBI raises the rate to 8.5%:
#1 Ram: Rs 10000 -> year end Rs 10850
#2 Sita: Rs 25000 -> year end Rs 27125
#3 Hari: Rs 50000 -> year end Rs 54250
sizeof. The object counter program is the standard question β write it with both a live count and a total. For static member functions, the key facts are: no this, cannot access non-static members, callable as Class::func(), and cannot be const or virtual. Mention the forgotten-definition linker error as a practical detail.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β¦