Clean Code на C++: как писать код, который не стыдно показать коллегам
Every C++ developer sooner or later faces a situation where their own code turns into a "dark forest" after a month. Variables like int a, functions 300 lines long, and magic numbers throughout the project — sound familiar? In this article, we will break down the principles of Clean Code as applied to C++, so that your code is not only functional but also understandable for others (and for your future self).
1. Naming variables, functions, and classes
A good name is half the battle. In C++, it is common to use camelCase for variables and functions, PascalCase for classes, and UPPER_CASE for constants (although modern C++ prefers constexpr).
Bad example:
int d; // elapsed time in daysfloat x; // salary multiplierbool fl; // is file loaded?Good example:
int elapsedDays;float salaryMultiplier;bool isFileLoaded;The rule is simple: the name should answer the question "what is this?" or "what does it do?". Avoid abbreviations (except for commonly accepted ones, e.g., idx for index). For boolean variables, use prefixes like is, has, can.
2. Functions should be small and do one thing
The classic Clean Code principle — a function should perform exactly one task. If you cannot come up with a short and clear name for a function — it is likely doing too much.
Bad example:
void processData(std::vector<int>& data) { // sorting std::sort(data.begin(), data.end()); // removing duplicates data.erase(std::unique(data.begin(), data.end()), data.end()); // calculating average double sum = 0; for (int val : data) sum += val; double avg = sum / data.size(); // output std::cout << "Average: " << avg << std::endl;}Good example:
std::vector<int> sortAndUnique(std::vector<int> data) { std::sort(data.begin(), data.end()); data.erase(std::unique(data.begin(), data.end()), data.end()); return data;}
double calculateAverage(const std::vector<int>& data) { if (data.empty()) return 0.0; double sum = std::accumulate(data.begin(), data.end(), 0.0); return sum / data.size();}
void printAverage(const std::vector<int>& data) { auto processed = sortAndUnique(data); double avg = calculateAverage(processed); std::cout << "Average: " << avg << std::endl;}Each function solves one task, is easy to test and reuse. The length of a function should not exceed 20-30 lines — this is a good guideline.
3. Avoid magic numbers and duplication
Magic numbers are numbers whose meaning is unclear from the context. Instead, use named constants.
Bad example:
double calculatePrice(double base) { return base * 1.2 + 5.0;}Good example:
constexpr double TAX_RATE = 1.2;constexpr double DELIVERY_FEE = 5.0;
double calculatePrice(double basePrice) { return basePrice * TAX_RATE + DELIVERY_FEE;}The same applies to code duplication. If you copy a block of code more than once — extract it into a function. The DRY (Don't Repeat Yourself) principle is the foundation of maintainable code.
4. Comments are not an excuse for bad code
The best comment is well-written code that requires no explanation. Comments should explain why the code does something non-obvious, not what it does.
Bad example:
Blogs
Book Recommendations
Read also
Jackson: Deserializing an Array of Objects in Java in 2025 — A Pro Guide
Monorepo with Rust: Code Organization for Large Projects
Algorithms and Data Structures in C#: A Complete Developer's Guide
Deploying a C++ Application on VPS: Step-by-Step Guide
Working with Databases in C++: PostgreSQL and MongoDB in Practice