Instance vs Static Members
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 27 of 104.
So far, every member variable you've created belongs to a specific object. When you create two Player objects, each has its own name and health. These are called instance members - they exist separately for each instance of the class.
But what if you need data shared across all objects? For example, tracking how many players exist in total.
This is where static members come in. A static member belongs to the class itself, not to any particular object.
class Player {
std::string name; // Instance member - each player has their own
int health; // Instance member
static int playerCount; // Static member - shared by ALL players
public:
Player(std::string n) : name(n), health(100) {
playerCount++; // Increment when any player is created
}
~Player() {
playerCount--; // Decrement when any player is destroyed
}
};The key difference: instance members are accessed through an object, while static members can be accessed through the class name itself. Think of instance members as "one per object" and static members as "one per class."
| Instance Members | Static Members |
|---|---|
| Unique to each object | Shared across all objects |
| Created when object is created | Exist before any object is created |
Accessed via object: player.health | Accessed via class: Player::playerCount |
Static members are useful for counters, configuration values, or any data that logically belongs to the class rather than individual objects.
Challenge
EasyLet's build a product inventory system that tracks both individual product details and overall inventory statistics using instance and static members.
You'll create two files to organize your code:
Product.h: Define aProductclass that manages individual products while also tracking inventory-wide data. Your class should have:- Instance members:
name(string) andprice(double) — unique to each product - A static member
totalProductsthat counts how many products currently exist - A static member
totalValuethat tracks the combined price of all products - A constructor that takes a name and price, initializes the instance members, and updates both static counters (increment count, add price to total value)
- A destructor that updates the static counters when a product is removed (decrement count, subtract price from total value)
- A
getInfo()method that returns a string in the format:"<name>: "<name>: $<price>"lt;price>" - A static method
getInventoryStats()that returns a string:"Products: <count>, Total Value: "Products: <count>, Total Value: $<value>"lt;value>"
- Instance members:
main.cpp: Demonstrate how static members are shared across all objects while instance members remain unique. Read two product names and their prices from input (name1, price1, name2, price2 — each on a separate line), then:- Print the initial inventory stats using the class name:
Product::getInventoryStats() - Create a scope block with curly braces and inside it create a
Productwith the first name and price. Print its info and the current inventory stats. - After the block ends (first product destroyed), print
"After first scope:"followed by the inventory stats - Create another
Productwith the second name and price. Print its info and the inventory stats. - Create a third
Productwith name"Bonus"and price5.00. Print the final inventory stats.
- Print the initial inventory stats using the class name:
Remember to define your static members outside the class in the header file (after the class definition). Format prices with two decimal places using std::fixed and std::setprecision(2) from <iomanip>.
Include your header file in main.cpp using #include "Product.h".
Cheat sheet
C++ supports two types of class members: instance members and static members.
Instance members are unique to each object - every instance has its own copy:
class Player {
std::string name; // Each player has their own name
int health; // Each player has their own health
};Static members are shared across all objects of a class - there's only one copy that belongs to the class itself:
class Player {
static int playerCount; // Shared by ALL players
public:
Player(std::string n) : name(n), health(100) {
playerCount++; // Increment shared counter
}
~Player() {
playerCount--; // Decrement when destroyed
}
};Key differences:
| Instance Members | Static Members |
|---|---|
| Unique to each object | Shared across all objects |
| Created when object is created | Exist before any object is created |
Accessed via object: player.health | Accessed via class: Player::playerCount |
Static methods can be called using the class name and can only access static members:
class Player {
static int playerCount;
public:
static int getPlayerCount() {
return playerCount; // Can only access static members
}
};
// Call using class name
int count = Player::getPlayerCount();Static members must be defined outside the class (typically in a .cpp file or after the class definition in a header):
int Player::playerCount = 0;Static members are useful for counters, shared configuration values, or any data that logically belongs to the class rather than individual objects.
Try it yourself
#include <iostream>
#include <string>
#include "Product.h"
using namespace std;
int main() {
// Read input
string name1;
double price1;
string name2;
double price2;
getline(cin, name1);
cin >> price1;
cin.ignore();
getline(cin, name2);
cin >> price2;
// TODO: Print initial inventory stats using Product::getInventoryStats()
// TODO: Create a scope block with curly braces
// Inside the block:
// - Create a Product with name1 and price1
// - Print its info using getInfo()
// - Print current inventory stats
// TODO: After the block ends, print "After first scope:"
// Then print the inventory stats
// TODO: Create another Product with name2 and price2
// Print its info and the inventory stats
// TODO: Create a third Product with name "Bonus" and price 5.00
// Print the final inventory stats
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesC++ Build & CompilationHeader Files & Source FilesNamespaces & ScopeIntroduction to OOP in C++Classes vs ObjectsThe 'this' PointerMethods (Member Functions)Attributes (Data Members)Ctors & Dtors BasicsRecap - Simple Calculator4Class Properties
Instance vs Static MembersGetters and SettersConst Member FunctionsMutable KeywordStatic Methods and VariablesFriend Functions & ClassesRecap - Bank Account Manager7Inheritance
Basic InheritanceInheritance Access LevelsCtor & Dtor Call OrderMethod OverridingVirtual Functions & VTableMultiple InheritanceVirtual InheritanceRecap - Employee Hierarchy2Memory Management
Stack vs Heap MemoryPointers and ReferencesDynamic Memory (new/delete)Smart Pointers in C++RAII in C++Recap - Dynamic Array Manager5Encapsulation
Access Specifiers in C++Access Specifiers In DepthInformation HidingStruct vs ClassNested & Inner ClassesRecap - Student Records System8Polymorphism
Compile vs Runtime PolymorphFunction OverloadingVirtual Functions RevisitedPure Virtual FunctionsAbstract ClassesInterface Design in C++Dynamic Casting & RTTIRecap - Shape Calculator3Constructors & Destructors
Default ConstructorParameterized ConstructorCopy ConstructorMove ConstructorConstructor Init ListsDelegating ConstructorsDestructor Deep DiveRule of Three / Five / ZeroRecap - String Class6Operator Overloading
Intro to Operator OverloadArithmetic Operator OverloadComparison Operator OverloadStream OperatorsAssignment Operator Overload[] and () Operator OverloadType Conversion OperatorsRecap - Matrix Class9Templates
Function TemplatesClass TemplatesTemplate SpecializationVariadic TemplatesSFINAE & Type Traits BasicsRecap - Generic Container