Spot the Bug

Here’s #2: “spot-the-bug” explanations for C++ classes, written super clearly, why it’s wrong, what happens, and how to think about it correctly—all based on Chapter 12 concepts.

I’ll talk to you like you’re 5, but still build the exam-ready understanding.


Common Class Mistakes (and Why They Hurt You)

Think of a class like a toy factory blueprint.
If the blueprint is wrong, every toy you make is broken.


Bug #1: Making data members public

Wrong way

class Movie {
public:
    string title;
    int year;
};

Why beginners do this

Because it’s easy:

movie.year = 1500;  // works

Why this is BAD

You just allowed any code anywhere to:

  • Put nonsense values in your object

  • Break your program later

  • Skip validation completely

Your object can now exist in an illegal state.

Example problem:

movie.year = -42;  // allowed, but makes no sense

Later:

cout << 2024 - movie.year; // huge number → bug

Correct thinking

Hide the data. Control access.

class Movie {
private:
    int year;

public:
    void set_year(int y) {
        if (y >= 1888) {
            year = y;
        }
    }
};

Rule to memorize:

If data must follow rules → it should be private


Bug #2: No validation in setters

Wrong way

void set_stars(int s) {
    stars = s;
}

Why this seems fine

“It’s just assigning a value.”

Why this breaks things

Now this is possible:

movie.set_stars(999);

Your object lies about reality.

Correct way

void set_stars(int s) {
    if (s < 1 || s > 5) {
        throw invalid_argument("Stars must be 1–5");
    }
    stars = s;
}

Kid rule:

Setters are security guards
They stop bad data at the door 🚪


Bug #3: Forgetting to initialize data (no constructor)

Wrong way

class Die {
private:
    int value;
};

Then:

Die d;
cout << d.get_value();  // ????

Why this is dangerous

value contains garbage memory.

It might be:

  • 3

  • -8421

  • 0

  • something random

Correct way (constructor)

class Die {
private:
    int value;

public:
    Die() {
        value = 1;
    }
};

Rule:

Every object should start life in a valid state

Constructors are the “birth instructions”


Bug #4: Doing work outside the class that belongs inside

Wrong way

int discount_amount = product.get_price() * product.get_discount_percent();

Why this is bad

  • Logic is scattered everywhere

  • Easy to make mistakes

  • If the formula changes → you must update many places

Correct way (read-only function)

double get_discount_amount() const {
    return price * discount_percent;
}

Now:

cout << product.get_discount_amount();

Rule:

If data depends on other data → calculate it inside the class


Bug #5: Making helper functions public

Wrong way

class Movie {
public:
    string to_upper(string s);
};

Why this is bad

Now other code can call:

movie.to_upper("hello");

But that function:

  • Wasn’t meant for outside use

  • Might change later

  • Isn’t part of the “interface”

Correct way

class Movie {
private:
    string to_upper(string s);
};

Rule:

If users shouldn’t touch it → make it private


Bug #6: Putting everything in the header file

Beginner mistake

// Movie.h
class Movie {
public:
    void set_year(int y) {
        if (y < 1888) throw invalid_argument("bad");
        year = y;
    }
};

Why this causes pain

  • Every change forces recompiling everything

  • Headers get huge

  • Harder to maintain

Correct structure

Header (.h) → what the class can do
Source (.cpp) → how it does it

Rule:

Small functions → okay inline
Big logic → .cpp file


Bug #7: Confusing struct and class

Wrong thinking

“I should always use class.”

Why that’s incorrect

Sometimes you just need a data bundle:

  • No rules

  • No protection

  • No reuse

Example: GameState

Correct thinking

Use

Choose

Simple data container

struct

Reusable object with rules

class

Rule:

No behavior, no rules → struct is fine


Bug #8: Letting other code handle randomness

Wrong way

int roll() {
    return rand() % 6 + 1;
}

Used everywhere.

Why this is bad

  • Must remember srand

  • Random logic duplicated

  • Easy to mess up

Correct way (Die class)

class Die {
public:
    void roll();
    int get_value() const;
};

Rule:

Hide messy details inside classes


Final Mental Model (EXAM GOLD)

When you see a class question, ask yourself:

  1. What data needs protection?

  2. What rules must be enforced?

  3. What should be private?

  4. What should be public?

  5. What should be calculated, not stored?

  6. How does the object start life?

If you can answer those → you understand Chapter 12.