Building a Complete Project
Build a comprehensive task management system combining all C++ concepts learned
This is it - the culmination of 100 days of C++ learning! Build a real-world task manager that demonstrates professional C++ development.
A Simple Example
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <fstream>
#include <algorithm>
enum class Priority { Low, Medium, High };
class Task {
std::string description;
Priority priority;
bool completed;
public:
Task(const std::string& desc, Priority p)
: description{desc}, priority{p}, completed{false} {}
void markComplete() { completed = true; }
bool isCompleted() const { return completed; }
const std::string& getDescription() const { return description; }
Priority getPriority() const { return priority; }
};
class TaskManager {
std::vector<std::unique_ptr<Task>> tasks;
std::string filename;
public:
TaskManager(const std::string& file) : filename{file} {
loadFromFile();
}
~TaskManager() {
saveToFile();
}
void addTask(const std::string& desc, Priority p) {
tasks.push_back(std::make_unique<Task>(desc, p));
}
void displayTasks() const {
std::cout << "\n=== Task List ===" << "\n";
for (size_t i{0}; i < tasks.size(); ++i) {
const auto& task = tasks[i];
std::cout << i + 1 << ". ";
std::cout << (task->isCompleted() ? "[X] " : "[ ] ");
std::cout << task->getDescription() << "\n";
}
}
void completeTask(size_t index) {
if (index < tasks.size()) {
tasks[index]->markComplete();
}
}
private:
void loadFromFile() {
std::ifstream file{filename};
if (!file) return;
std::string line;
while (std::getline(file, line)) {
if (!line.empty()) {
tasks.push_back(std::make_unique<Task>(line, Priority::Medium));
}
}
}
void saveToFile() {
std::ofstream file{filename};
for (const auto& task : tasks) {
if (!task->isCompleted()) {
file << task->getDescription() << "\n";
}
}
}
};
int main() {
TaskManager manager{"tasks.txt"};
manager.addTask("Learn C++ basics", Priority::High);
manager.addTask("Build a project", Priority::Medium);
manager.addTask("Master design patterns", Priority::Low);
manager.displayTasks();
std::cout << "\nCompleting first task..." << "\n";
manager.completeTask(0);
manager.displayTasks();
return 0;
}
Breaking It Down
RAII for File Management
- What we did: Files are managed automatically in constructor/destructor
- Benefit: No manual file closing needed, even if exceptions occur
- Pattern: Load in constructor, save in destructor ensures data persistence
- Remember: This is professional C++ - resources manage themselves
Modern C++ Features
- Smart pointers: std::unique_ptr prevents memory leaks automatically
- Enum class: Type-safe enumerations prevent accidental misuse
- Uniform initialization: Braces {} prevent narrowing conversions
- Remember: Modern C++ is safer and more expressive than C-style code
Clean Architecture
- Separation of concerns: Task handles data, TaskManager handles logic
- Encapsulation: Private data with public interface
- Const correctness: Methods that don't modify are marked const
- Remember: Good design makes code easier to understand and maintain
Professional Practices
- Error handling: Check file operations before using them
- Resource management: RAII ensures proper cleanup
- Type safety: Using enums and strong types instead of raw values
- Remember: These practices prevent bugs in production code
Why This Matters
- This is the culmination of 100 days of C++ learning - putting everything together into a production-quality application.
- You'll build a real-world application that showcases professional C++ development: proper error handling, RAII resource management, modern syntax, const correctness, and clean architecture.
- This project proves you can build production-quality C++ software that follows industry best practices.
Critical Insight
This project demonstrates professional C++ development. Notice how we use:
- RAII for resource management (files close automatically) - Smart pointers (no manual memory management) - Exceptions for errors (not error codes) - Const correctness (getters are const) - Modern C++ (auto, range-for, enum class) - Separation of concerns (Task, TaskManager, UI separate) - Proper encapsulation
This is how real C++ applications are built! Every concept you've learned over 100 days comes together here. You've gone from "Hello World" to building production-quality software. You're now a C++ developer.
Best Practices
Use RAII everywhere: Let objects manage their own resources automatically.
Prefer smart pointers: Use std::unique_ptr or std::shared_ptr instead of raw new/delete.
Apply const correctness: Mark methods const when they don't modify state.
Separate concerns: Keep data, logic, and UI in separate classes for maintainability.
Handle errors properly: Check for file operations failures and handle them gracefully.
Common Mistakes
Forgetting destructors: Without proper cleanup, resources leak. Use RAII to automate cleanup.
Raw pointer ownership: Using raw pointers for ownership requires manual memory management and invites leaks.
No error handling: Not checking if file operations succeed leads to crashes in production.
Poor separation: Mixing UI and logic makes code hard to test and maintain.
Debug Challenge
This task manager leaks memory. Click the highlighted line to fix it using smart pointers:
Quick Quiz
- Why do we load tasks in the constructor and save in the destructor?
- Why use std::unique_ptr instead of raw pointers?
- What does const correctness mean in this project?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once