Static vs non-static in C++
In C++, the keywords static define how class members behave in terms of
memory, accessibility, and lifetime.
Static can be used with:
• Variables (inside functions, classes, or globally)
• Member functions
• Data members (class variables)
1. Static Member Variables
• Shared by all objects of the class.
• Exists only once, no matter how many objects are created.
• Can be accessed without creating an object (using the class name)
• Initialized outside the class.
#include <iostream>
using namespace std;
class Student {
public:
static int count; // shared across all objects
void increment() {
count++;
}
void show() {
cout << "Count: " << count << endl;
}
};
// Definition of static member
int Student::count = 0;
int main() {
// Creating objects using new
Student* s1 = new Student();
Student* s2 = new Student();
Student* s3 = new Student();
// Each object calls increment
s1->increment();
s2->increment();
s3->increment();
// Call show using any object (same value will be shown)
s1->show(); // Output: Count: 3
// Clean up memory
delete s1;
delete s2;
delete s3;
return 0;
}
2. Static Member Functions
• Can be called without creating an object.
• Only access static data members (cannot access this or non-static
members).
• Belong to the class itself, not to any specific object.
#include <iostream>
using namespace std;
class Student {
public:
static int count; // shared across all objects
// Static function to increment count
static void increment() {
count++;
}
// Static function to show the current count
static void show() {
cout << "Count: " << count << endl;
}
};
// Define the static member outside the class
int Student::count = 0;
int main() {
// Create objects using new
Student* s1 = new Student();
Student* s2 = new Student();
// Call static function using class name
Student::increment();
// Call static function using object
s1->increment();
s2->increment();
// Show count using both class and object
Student::show(); // Output: Count: 3
s1->show(); // Output: Count: 3 (same value)
// Clean up
delete s1;
delete s2;
return 0;
}
Feature Static Members Non-Static Members
Belongs to Class Object (instance)
Memory Allocation Once (shared) Per object
Access without object (using ClassName::)
Initialization Outside class Inside constructor
Can access this?
Lifetime Entire program Object's lifetime
Inheritance in C++
• Inheritance is a fundamental Object-Oriented Programming
(OOP) concept in C++
• Allows a new class (derived/child class) to inherit properties and
behaviors from an existing class (base/parent class).
• Syntax:
class Base {
// Base class members
};
class Derived : access-specifier Base {
// Derived class members
};
Advantages of Inheritance in C++
• Code Reusability (Avoids Redundancy)
Reuse existing code from the base class without rewriting it.
Reduces duplication, making the code more maintainable.
• Method Overriding (Runtime Polymorphism)
Modify or extend base class methods in the derived class.
• Extensibility (Easy to Add New Features)
Enhance existing classes without modifying the original code
(Open/Closed Principle)
• Hierarchical Organization (Better Structure)
Improves readability by logically grouping related classes.
Types of Inheritance in C++
Type Description
Single Inheritance A derived class inherits from one base class.
Multiple A derived class inherits from multiple base
Inheritance classes.
Multilevel A derived class inherits from another derived class
Inheritance (chain of inheritance).
Hierarchical Multiple derived classes inherit from a single base
Inheritance class.
Hybrid Inheritance Combination of multiple and multilevel inheritance.
C++ supports three access specifiers in inheritance:
Access Specifier Effect on Inheritance
Public members → Public in derived class
public
Protected members → Protected in derived class
Public & Protected members → Protected in derived
protected
class
private Public & Protected members → Private in derived class
1. Single Inheritance
• A class inherits from only one base class.
• Syntax:
class Base {
// Base class members
};
class Derived : access-specifier Base {
// Derived class members
};
• Example:
#include <iostream>
using namespace std;
class Human {
public:
void eat() {
cout << "Human is eating." << endl;
}
};
class Student : public Human { // Single Inheritance
public:
void study() {
cout << "Student is studying." << endl;
}
};
int main() {
Student s;
s.eat(); // Inherited from Human
s.study(); // Own function
return 0;
}
2. Multiple Inheritance
• A class can inherit from more than one base class.
• Syntax:
class Derived : access-specifier Base1, access-specifier Base2, ...{
// Derived class members
};
• Example:
class Student {
public:
void study() {
cout << "Studying..." << endl;
}
};
class Programmer {
public:
void code() {
cout << "Coding..." << endl;
}
};
// Multiple Inheritance
class CSE_Student : public Student, public Programmer {
public:
void debug() {
cout << "Debugging code..." << endl;
}
};
int main() {
CSE_Student cs;
cs.study(); // From Student
cs.code(); // From Programmer
cs.debug(); // Own function
return 0;
}
3. Multilevel Inheritance
• A class is derived from another derived class (forming a chain).
• Syntax:
class Base { /* ... */ };
class Derived1 : public Base { /* ... */ };
class Derived2 : public Derived1 { /* ... */ };
• Example
class Human {
public:
void breathe() {
cout << "Human is breathing." << endl;
}
};
class Student : public Human { // Level 1
public:
void study() {
cout << "Student is studying." << endl;
}
};
class CSE_Student : public Student { // Level 2 (Multilevel)
public:
void code() {
cout << "CSE student is coding." << endl;
}
};
int main() {
CSE_Student cs;
cs.breathe(); // From Human
cs.study(); // From Student
cs.code(); // Own function
return 0;
}
4. Hierarchical Inheritance
• Multiple derived classes inherit from a single base class.
• Syntax:
class Base {
// Base class members
};
class Derived1 : access-specifier Base {
// Derived1 class members
};
class Derived2 : access-specifier Base {
// Derived2 class members
};
// ... more derived classes can inherit from Base
• Example:
class Human {
public:
void sleep() {
cout << "Human is sleeping." << endl;
}
};
class Student : public Human { // Hierarchical
public:
void attendClass() {
cout << "Student attends class." << endl;
}
};
class Teacher : public Human { // Hierarchical
public:
void teach() {
cout << "Teacher teaches." << endl;
}
};
int main() {
Student s;
Teacher t;
s.sleep(); // From Human
s.attendClass(); // Own function
t.sleep(); // From Human
t.teach(); // Own function
return 0;
}
5. Hybrid Inheritance
• A combination of multiple and multilevel inheritance.
• Diamond Problem can arise here.
Human (Base)
/ \
Student Teacher (Intermediate)
\ /
TA (Teaching Assistant) (Derived)
• TA inherits from both Student and Teacher, which both inherit
from Human.
• This creates two copies of Human in TA, leading to ambiguity.
• Example:
#include <iostream>
using namespace std;
class Human {
public:
void breathe() {
cout << "Human is breathing." << endl;
}
};
class Student : public Human { // Inherits Human
public:
void study() {
cout << "Student is studying." << endl;
}
};
class Teacher : public Human { // Also inherits Human
public:
void teach() {
cout << "Teacher is teaching." << endl;
}
};
// TA inherits from both Student and Teacher (Diamond Problem)
class TA : public Student, public Teacher {
public:
void assist() {
cout << "TA is assisting." << endl;
}
};
int main() {
TA ta;
ta.study(); // OK (from Student)
ta.teach(); // OK (from Teacher)
// ta.breathe();
// ERROR: Ambiguous (which breathe()? Student::Human or Teacher::Human?)
return 0;
}
1. Diamond Problem Occurs When:
o A class inherits from two classes that share a common ancestor.
o Results in duplicate base class members.
2. Solution: Virtual Inheritance
o Use virtual keyword when inheriting the shared base class:
class Student : virtual public Human { ... };
class Teacher : virtual public Human { ... };
o Ensures only one copy of the base class exists in the derived class.
class Human {
public:
void breathe() {
cout << "Human is breathing." << endl;
}
};
// Virtual inheritance to avoid duplicate Human
class Student : virtual public Human {
public:
void study() {
cout << "Student is studying." << endl;
}
};
// Virtual inheritance to avoid duplicate Human
class Teacher : virtual public Human {
public:
void teach() {
cout << "Teacher is teaching." << endl;
}
};
// TA now has only one copy of Human
class TA : public Student, public Teacher {
public:
void assist() {
cout << "TA is assisting." << endl;
}
};
int main() {
TA ta;
ta.breathe(); // OK (only one Human copy)
ta.study(); // From Student
ta.teach(); // From Teacher
ta.assist(); // Own function
return 0;
}
Comparison: With vs Without Virtual Inheritance
Scenario ta.breathe() Works? Copies of Human in TA
Without virtual (Ambiguous) 2 (one per parent)
With virtual 1 (shared)
Types of Inheritance (Graphical Representation):