C++ and Object-Oriented Programming

File Handling in C++; Pointers in C++ — Smart Pointers; Friend Functions and Classes

C-CAT

File Handling in C++

C++ File Streams

#include <fstream>
using namespace std;

// Write to file
ofstream outFile("data.txt");
if (outFile.is_open()) {
    outFile <<
"Name: Alice" << endl;
    outFile << "Age: 25" << endl;
    outFile.close();
}

// Read from file
ifstream inFile("data.txt");
string line;
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();

// Both read and write
fstream rwFile("data.txt", ios::in | ios::out);

Binary File I/O

struct Employee {
    int id;
    char name[50];
    double salary;
};

// Write binary
ofstream binOut("employees.bin", ios::binary);
Employee e = {1, "Alice",
55000.0};
binOut.write((char*)&e, sizeof(Employee));
binOut.close();

// Read binary
ifstream binIn("employees.bin", ios::binary);
Employee loaded;
binIn.read((char*)&loaded, sizeof(Employee));
cout << loaded.id << " " << loaded.name << " " << loaded.salary << endl;
binIn.close();

Pointers in C++ — Smart Pointers

C++ Smart Pointers (C++11)

Smart pointers automatically manage memory — no manual delete needed.

#include <memory>
using namespace std;

// unique_ptr: sole ownership; auto-deleted when out of scope
unique_ptr<int> p1 =
make_unique<int>(42);
cout << *p1 << endl;   // 42
// No delete needed! Automatically freed

unique_ptr<int[]> arr = make_unique<int[]>(5);   // dynamic array
arr[0] = 10;

// shared_ptr: shared ownership; freed when last reference gone
shared_ptr<int> sp1 =
make_shared<int>(100);  // ref count = 1
{
    shared_ptr<int> sp2 = sp1;    // ref count =
2
    cout << *sp2 << endl;         // 100
}  // sp2 goes out of scope; ref count = 1
// sp1
still valid

// weak_ptr: non-owning reference; avoid circular references
weak_ptr<int> wp = sp1;
if (auto sp = wp.lock()) {   // lock() returns shared_ptr if valid
    cout << *sp << endl;
}

References in C++

int x = 10;
int &ref = x;   // ref is a reference (alias) to x

ref = 20;       // modifies x!
cout << x << endl;   // 20

// Pass by reference to function
void increment(int &n) {
    n++;   // modifies caller's
variable
}

int val = 5;
increment(val);
cout << val << endl;   // 6

Friend Functions and Classes

Friend Function

A friend function has access to all private and protected members of a class, but is NOT a member of the class.

class Box {
private:
    double length, width, height;

public:
    Box(double l, double w, double h) : length(l), width(w), height(h) {}

    friend double volume(const Box &b);          // declare as friend
    friend ostream& operator<<(ostream&, const Box&);
};

// Friend function — not a member but has access to private data
double volume(const Box &b)
{
    return b.length * b.width * b.height;   // can access private!
}

ostream& operator<<(ostream &out, const Box &b) {
    out << "[" << b.length << "x" <<
b.width << "x" << b.height << "]";
    return out;
}

int main() {
    Box box(3, 4, 5);
    cout << "Volume: " << volume(box) << endl;  // 60
    cout << box << endl;  // [3x4x5]
    return 0;
}

C++ Stream Files

ifstream reads files, ofstream writes files and fstream can perform both. Opening modes include input, output, append, truncate and binary. Stream state records end-of-file, format failure and serious I/O failure. Extraction should be used as the loop condition so the final unsuccessful read is not processed.

Text mode performs formatted conversion while binary mode transfers bytes. Writing an object’s raw memory is not a portable serialization format because padding, pointers and representation vary. A durable file format writes defined fields with an explicit version and validates input before constructing objects.

Smart Pointers and Friendship

unique_ptr represents exclusive ownership and moves rather than copies. shared_ptr uses a control block to count shared owners. weak_ptr observes a shared object without extending its lifetime and breaks ownership cycles. make_unique and make_shared construct owned objects safely. A raw pointer may still represent non-owning access when lifetime is guaranteed elsewhere.

A friend function or class may access private and protected members even though it is not a member or derived type. Friendship is granted explicitly, is not inherited and is not automatically mutual. It is useful for tightly coupled operations such as symmetric operators but broad friendship weakens encapsulation and should remain narrow.

Continue learning

Related notes

Put this topic into timed practice

Open mock tests when you want full-exam pacing, or keep drilling in practice mode.