📘 Learning Objectives
After completing this chapter, you will: - Understand advanced C++ features and concepts - Learn about object-oriented programming in C++ - Explore the Standard Template Library (STL) - Understand memory management and RAII - Get introduced to modern C++ features
🎯 Key Concepts
1. Advanced Classes and Inheritance
- Class inheritance: Base and derived classes
- Virtual functions: Polymorphism and dynamic dispatch
- Abstract classes: Pure virtual functions
- Constructor and destructor: Object lifecycle
- Access control: Public, private, protected inheritance
2. Templates and Generic Programming
- Function templates: Generic functions
- Class templates: Generic classes
- Template specialization: Specialized implementations
- Template instantiation: How templates work
- Generic algorithms: Template-based algorithms
3. Standard Template Library (STL)
- Containers: vector, list, map, set, etc.
- Iterators: Container traversal
- Algorithms: sort, find, transform, etc.
- Function objects: Predicates and comparators
- STL design: Generic programming principles
4. Memory Management
- Dynamic memory: new and delete
- Smart pointers: unique_ptr, shared_ptr
- RAII: Resource Acquisition Is Initialization
- Memory leaks: Prevention and detection
- Exception safety: Exception-safe memory management
5. Modern C++ Features
- C++11 features: auto, lambda, range-based for
- C++14 features: Generic lambdas, auto return
- C++17 features: Structured bindings, if constexpr
- C++20 features: Concepts, ranges, coroutines
- Best practices: Modern C++ coding style
🧩 Practice Exercises
Exercise 4.1: Inheritance and Polymorphism
Create a class hierarchy with virtual functions.
Exercise 4.2: Templates
Implement function and class templates.
Exercise 4.3: STL Usage
Use STL containers and algorithms.
Exercise 4.4: Smart Pointers
Use smart pointers for memory management.
Exercise 4.5: Modern C++ Features
Apply modern C++ features in your code.
💻 Code Examples
Inheritance and Polymorphism
#include <iostream>
#include <memory>
#include <vector>
class Shape {
public:
virtual double area() const = 0;
virtual void draw() const = 0;
virtual ~Shape() = default;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override { return 3.14159 * radius * radius; }
void draw() const override { std::cout << "Drawing a circle" << std::endl; }
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override { return width * height; }
void draw() const override { std::cout << "Drawing a rectangle" << std::endl; }
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5.0));
shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
for (const auto& shape : shapes) {
shape->draw();
std::cout << "Area: " << shape->area() << std::endl;
}
return 0;
}
Templates
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T>
T maximum(const T& a, const T& b) {
return (a > b) ? a : b;
}
template<typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) {
throw std::runtime_error("Stack is empty");
}
T top = elements.back();
elements.pop_back();
return top;
}
bool empty() const {
return elements.empty();
}
};
int main() {
std::cout << maximum(10, 20) << std::endl;
std::cout << maximum(3.14, 2.71) << std::endl;
Stack<int> int_stack;
int_stack.push(1);
int_stack.push(2);
int_stack.push(3);
while (!int_stack.empty()) {
std::cout << int_stack.pop() << " ";
}
std::cout << std::endl;
return 0;
}
STL Usage
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
int main() {
// Vector operations
std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 7, 4, 6};
std::sort(numbers.begin(), numbers.end());
std::cout << "Sorted numbers: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Map usage
std::map<std::string, int> ages;
ages["Alice"] = 25;
ages["Bob"] = 30;
ages["Charlie"] = 35;
for (const auto& pair : ages) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
// Set usage
std::set<int> unique_numbers = {1, 2, 2, 3, 3, 3, 4, 5};
std::cout << "Unique numbers: ";
for (int num : unique_numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
Smart Pointers
#include <iostream>
#include <memory>
class Resource {
public:
Resource(int id) : id_(id) {
std::cout << "Resource " << id_ << " created" << std::endl;
}
~Resource() {
std::cout << "Resource " << id_ << " destroyed" << std::endl;
}
int getId() const { return id_; }
private:
int id_;
};
int main() {
// unique_ptr
auto resource1 = std::make_unique<Resource>(1);
std::cout << "Resource 1 ID: " << resource1->getId() << std::endl;
// shared_ptr
auto resource2 = std::make_shared<Resource>(2);
std::cout << "Resource 2 ID: " << resource2->getId() << std::endl;
// weak_ptr
std::weak_ptr<Resource> weak_resource = resource2;
if (auto locked = weak_resource.lock()) {
std::cout << "Weak pointer locked, ID: " << locked->getId() << std::endl;
}
return 0;
}
Modern C++ Features
#include <iostream>
#include <vector>
#include <algorithm>
#include <optional>
int main() {
// C++11: auto and lambda
std::vector<int> numbers = {1, 2, 3, 4, 5};
auto doubled = [](int x) { return x * 2; };
std::transform(numbers.begin(), numbers.end(), numbers.begin(), doubled);
// C++17: structured bindings
std::map<std::string, int> data = {{"Alice", 25}, {"Bob", 30}};
for (const auto& [name, age] : data) {
std::cout << name << ": " << age << std::endl;
}
// C++17: if constexpr
template<typename T>
void process(T value) {
if constexpr (std::is_integral_v<T>) {
std::cout << "Integer: " << value << std::endl;
} else {
std::cout << "Non-integer: " << value << std::endl;
}
}
process(42);
process(3.14);
return 0;
}
🎓 Key Takeaways
- C++ supports multiple programming paradigms - procedural, object-oriented, and generic
- Templates provide powerful generic programming capabilities
- STL offers comprehensive containers and algorithms for common tasks
- Smart pointers automate memory management and prevent leaks
- Modern C++ features make code more expressive and safer
🔗 Next Steps
After completing the tour of C++, proceed to Chapter 5 to learn about user-defined types.
📚 Additional Resources
- C++ Reference: Advanced Features
- C++ Core Guidelines: Modern C++
- Practice with advanced C++ features