C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
23: Classes and Objects
I see this all the time when students first hit OOP: they treat a class and an object as interchangeable terms. You'll hear someone say, "I'm going to create a Player class," when what they actually mean is they're creating a specific player character for their game. It sounds like a semantic nitpick, but if you don't grasp the distinction, you'll find yourself staring at compiler errors that make zero sense.
The "Class is the Object" Fallacy
If you think a class is the object, you're essentially confusing a blueprint for a house with the actual house you can live in. You can't open the front door of a blueprint. You can't paint the walls of a blueprint. Similarly, in C++, you cannot call a member function on a class itself—you can only call it on an instance of that class.
// This is the blueprint (The Class)
class Player {
public:
int health = 100;
void takeDamage(int amount) {
health -= amount;
}
};
int main() {
// This is WRONG. The class doesn't have health;
// it only defines that Players SHOULD have health.
// Player::takeDamage(10); // Compiler error!
}
Defining the Blueprint and Casting the Instance
To actually use that logic, you have to instantiate the class. When you do this, the computer carves out a specific chunk of memory to hold the data for that one specific object. I like to think of this as "casting" the object from the mold of the class.
Once you've created an object, you can have multiple versions of that class, each with its own independent state. If you have two players, one taking damage doesn't magically hurt the other. That's the power of objects.
int main() {
Player player1; // Object 1
Player player2; // Object 2
player1.takeDamage(20);
// player1.health is now 80
// player2.health is still 100
}
Guarding the Gates with Access Specifiers
Now, you might be tempted to leave everything public because it's easier. Trust me, don't do that. In a real-world project, letting any part of your code reach inside an object and change its variables is a recipe for disaster. This is where private comes in.
By marking data as private, you're telling the rest of the program: "You can't touch this directly. If you want to change the health, you have to use the method I provided." This is called encapsulation. It allows you to add validation—like making sure health never drops below zero—without having to hunt down every single line of code in your project that modifies health.
class Player {
private:
int health = 100; // No one outside the class can touch this
public:
void takeDamage(int amount) {
health -= amount;
if (health < 0) health = 0; // Logic is centralized here!
}
int getHealth() { // A "getter" to let people see the value without changing it
return health;
}
};
📋 Practical Task
Build a Digital Thermostat Controller
Your task is to create a Thermostat class that manages a home's temperature. You need to ensure that the temperature cannot be set to dangerous levels (too hot or too cold) by using a private member variable and a public setter method.
Requirements:
- Create a
Thermostatclass. - Include a private
double currentTempvariable. - Implement a public method
setTemperature(double newTemp). This method should only update the temperature if the value is between 50.0 and 90.0 degrees Fahrenheit. If the value is outside this range, it should print "Invalid temperature!" and refuse the change. - Implement a public method
getCurrentTemp()that returns the current value. - In your
main()function, instantiate two separate thermostat objects (e.g.,livingRoomandbedroom). - Attempt to set one to a valid temperature and the other to an invalid one (e.g., 110.0), then print both results to verify they are independent.
There are no comments for now.