C++98corebeginner
Classes
C++98 · The Foundation · Compiler flag: -std=c++98
Explanation
User-defined types combining data and functions to model entities.
Real-World Scenario
Represent a car in a racing game with speed and accelerate methods.
Quick Snippet
snippet.cpp
class Car { public: int speed; void drive() {}; };Full Example
classes.cpp
// CodeNebula - C++98 Example: Classes
// Compile: g++ -std=c++98 -Wall -Wextra -o example classes.cpp
// Demonstrates classes in C++98: data members, member functions, access
// specifiers (public/private/protected), constructors, the this pointer,
// const member functions, static members, and friend functions.
#include <iostream>
#include <cstring>
#include <cmath>
// ------------------------------------------------------------------
// 1. Basic class with private data and public interface
// ------------------------------------------------------------------
class Rectangle {
private:
double width_;
double height_;
public:
// Constructor
Rectangle(double w, double h) : width_(w), height_(h) {}
// Getters (const member functions - promise not to modify the object)
double getWidth() const { return width_; }
double getHeight() const { return height_; }
// Setters
void setWidth(double w) { width_ = w; }
void setHeight(double h) { height_ = h; }
// Computation methods
double area() const { return width_ * height_; }
double perimeter() const { return 2.0 * (width_ + height_); }
bool isSquare() const { return width_ == height_; }
// Display
void print() const
{
std::cout << "Rectangle(" << width_ << " x " << height_ << ")";
}
};
// ------------------------------------------------------------------
// 2. Class demonstrating all three access specifiers
// ------------------------------------------------------------------
class BankAccount {
private:
char owner_[50];
double balance_;
int transactionCount_;
// Private helper
void logTransaction(const char* type, double amount)
{
++transactionCount_;
std::cout << " [Transaction #" << transactionCount_ << "] "
<< type << ": $" << amount << std::endl;
}
public:
BankAccount(const char* owner, double initialBalance)
: balance_(initialBalance), transactionCount_(0)
{
std::strncpy(owner_, owner, 49);
owner_[49] = '\0';
}
void deposit(double amount)
{
if (amount > 0) {
balance_ += amount;
logTransaction("Deposit", amount);
}
}
bool withdraw(double amount)
{
if (amount > 0 && amount <= balance_) {
balance_ -= amount;
logTransaction("Withdrawal", amount);
return true;
}
std::cout << " Withdrawal of $" << amount << " denied." << std::endl;
return false;
}
double getBalance() const { return balance_; }
const char* getOwner() const { return owner_; }
void printStatement() const
{
std::cout << " Account: " << owner_
<< " | Balance: $" << balance_
<< " | Transactions: " << transactionCount_ << std::endl;
}
};
// ------------------------------------------------------------------
// 3. Class demonstrating the 'this' pointer
// ------------------------------------------------------------------
class Vector2D {
private:
double x_;
double y_;
public:
Vector2D(double x, double y) : x_(x), y_(y) {}
// 'this' pointer returns reference for method chaining
Vector2D& setX(double x) { this->x_ = x; return *this; }
Vector2D& setY(double y) { this->y_ = y; return *this; }
Vector2D& scale(double factor)
{
this->x_ *= factor;
this->y_ *= factor;
return *this;
}
Vector2D& add(const Vector2D& other)
{
this->x_ += other.x_;
this->y_ += other.y_;
return *this;
}
double magnitude() const
{
return std::sqrt(x_ * x_ + y_ * y_);
}
void print() const
{
std::cout << "(" << x_ << ", " << y_ << ")";
}
};
// ------------------------------------------------------------------
// 4. Class with static members
// ------------------------------------------------------------------
class Counter {
private:
int id_;
static int count_; // shared across all instances
static int nextId_;
public:
Counter() : id_(nextId_++)
{
++count_;
}
~Counter()
{
--count_;
}
int getId() const { return id_; }
static int getCount() { return count_; }
void print() const
{
std::cout << " Counter id=" << id_
<< " (total active: " << count_ << ")" << std::endl;
}
};
// Static member definitions (must be outside the class)
int Counter::count_ = 0;
int Counter::nextId_ = 1;
// ------------------------------------------------------------------
// 5. Class with friend function
// ------------------------------------------------------------------
class Temperature {
private:
double celsius_;
public:
Temperature(double c) : celsius_(c) {}
double getCelsius() const { return celsius_; }
double getFahrenheit() const { return celsius_ * 9.0 / 5.0 + 32.0; }
// Friend function can access private members
friend Temperature addTemperatures(const Temperature& a, const Temperature& b);
friend void printDetailed(const Temperature& t);
};
Temperature addTemperatures(const Temperature& a, const Temperature& b)
{
// Can access private celsius_ because it's a friend
return Temperature(a.celsius_ + b.celsius_);
}
void printDetailed(const Temperature& t)
{
// Can access private celsius_ directly
std::cout << " " << t.celsius_ << " C = " << t.getFahrenheit() << " F" << std::endl;
}
// ------------------------------------------------------------------
// 6. Struct vs Class (only difference: default access)
// ------------------------------------------------------------------
struct Point { // default: public
double x;
double y;
Point(double px, double py) : x(px), y(py) {}
double distanceTo(const Point& other) const
{
double dx = x - other.x;
double dy = y - other.y;
return std::sqrt(dx * dx + dy * dy);
}
};
int main()
{
// ------------------------------------------------------------------
// Demo 1: Basic class usage
// ------------------------------------------------------------------
std::cout << "=== Rectangle Class ===" << std::endl;
Rectangle r(5.0, 3.0);
std::cout << " ";
r.print();
std::cout << std::endl;
std::cout << " Area: " << r.area() << std::endl;
std::cout << " Perimeter: " << r.perimeter() << std::endl;
std::cout << " Is square? " << (r.isSquare() ? "yes" : "no") << std::endl;
r.setWidth(4.0);
r.setHeight(4.0);
std::cout << " After resize: ";
r.print();
std::cout << std::endl;
std::cout << " Is square? " << (r.isSquare() ? "yes" : "no") << std::endl;
std::cout << std::endl;
// ------------------------------------------------------------------
// Demo 2: Encapsulation with BankAccount
// ------------------------------------------------------------------
std::cout << "=== BankAccount Class ===" << std::endl;
BankAccount acct("Alice", 1000.0);
acct.printStatement();
acct.deposit(500.0);
acct.withdraw(200.0);
acct.withdraw(2000.0); // denied
acct.printStatement();
std::cout << std::endl;
// ------------------------------------------------------------------
// Demo 3: Method chaining with 'this'
// ------------------------------------------------------------------
std::cout << "=== Vector2D - Method Chaining ===" << std::endl;
Vector2D v(1.0, 2.0);
std::cout << " Original: ";
v.print();
std::cout << std::endl;
// Chain multiple operations
v.setX(3.0).setY(4.0).scale(2.0);
std::cout << " After setX(3).setY(4).scale(2): ";
v.print();
std::cout << std::endl;
std::cout << " Magnitude: " << v.magnitude() << std::endl;
Vector2D v2(1.0, 1.0);
v.add(v2).scale(0.5);
std::cout << " After add(1,1).scale(0.5): ";
v.print();
std::cout << std::endl;
std::cout << std::endl;
// ------------------------------------------------------------------
// Demo 4: Static members
// ------------------------------------------------------------------
std::cout << "=== Static Members ===" << std::endl;
std::cout << " Active counters: " << Counter::getCount() << std::endl;
Counter c1;
Counter c2;
Counter c3;
c1.print();
c2.print();
c3.print();
{
Counter c4;
c4.print();
std::cout << " (c4 about to go out of scope)" << std::endl;
}
std::cout << " After c4 destroyed, active: " << Counter::getCount() << std::endl;
std::cout << std::endl;
// ------------------------------------------------------------------
// Demo 5: Friend function
// ------------------------------------------------------------------
std::cout << "=== Friend Function ===" << std::endl;
Temperature t1(100.0);
Temperature t2(37.0);
std::cout << " t1: ";
printDetailed(t1);
std::cout << " t2: ";
printDetailed(t2);
Temperature sum = addTemperatures(t1, t2);
std::cout << " t1 + t2: ";
printDetailed(sum);
std::cout << std::endl;
// ------------------------------------------------------------------
// Demo 6: struct (default public) vs class (default private)
// ------------------------------------------------------------------
std::cout << "=== Struct vs Class ===" << std::endl;
Point p1(0.0, 0.0);
Point p2(3.0, 4.0);
// Members are public by default in struct
std::cout << " p1 = (" << p1.x << ", " << p1.y << ")" << std::endl;
std::cout << " p2 = (" << p2.x << ", " << p2.y << ")" << std::endl;
std::cout << " Distance: " << p1.distanceTo(p2) << std::endl;
return 0;
}
/*
Expected output:
=== Rectangle Class ===
Rectangle(5 x 3)
Area: 15
Perimeter: 16
Is square? no
After resize: Rectangle(4 x 4)
Is square? yes
=== BankAccount Class ===
Account: Alice | Balance: $1000 | Transactions: 0
[Transaction #1] Deposit: $500
[Transaction #2] Withdrawal: $200
Withdrawal of $2000 denied.
Account: Alice | Balance: $1300 | Transactions: 2
=== Vector2D - Method Chaining ===
Original: (1, 2)
After setX(3).setY(4).scale(2): (6, 8)
Magnitude: 10
After add(1,1).scale(0.5): (3.5, 4.5)
=== Static Members ===
Active counters: 0
Counter id=1 (total active: 3)
Counter id=2 (total active: 3)
Counter id=3 (total active: 3)
Counter id=4 (total active: 4)
(c4 about to go out of scope)
After c4 destroyed, active: 3
=== Friend Function ===
t1: 100 C = 212 F
t2: 37 C = 98.6 F
t1 + t2: 137 C = 278.6 F
=== Struct vs Class ===
p1 = (0, 0)
p2 = (3, 4)
Distance: 5
*/
Run command
g++ -std=c++98 -Wall -Wextra -o example classes.cpp