Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟢 Foundation  ·  Lesson 14

C++ Coding Best Practices

In this lesson: Write clean, safe C++ — RAII, const, references, smart pointers, naming — bad vs good examples. In Hindi & English.

What are coding best practices?

A C++ program can compile, run and even give the right output — and still be hard to read, easy to break and full of hidden bugs. Best practices are the habits experienced programmers follow so that code stays correct, readable and easy to change. They are not extra syntax to learn; they are choices you make every time you write a line.

In one line: write code that the next person — including you, three months later — can read, trust and change without fear.

This lesson collects the practices that matter most for students and beginners, each with a short "avoid" and "prefer" example.

1. Names that explain themselves

A good name removes the need for a comment. Use nouns for variables, verbs for functions, and avoid single letters except loop counters.

C++
// Avoid
int a, b, c;
int f(int x, int y) { return x * y / 100; }

// Prefer
int totalMarks, maxMarks, percentage;
int calculatePercentage(int obtained, int maximum) {
    return obtained * 100 / maximum;
}

Pick one style and stick to it: camelCase for variables and functions and PascalCase for classes is common. Constants are often written as MAX_STUDENTS or kMaxStudents.

2. Consistent indentation and braces

Indent each block by the same amount (4 spaces is typical) and always use braces, even for a single statement. Missing braces is a classic source of bugs:

C++
// Avoid — only the first line is inside the if
if (marks >= 33)
    cout << "Pass\n";
    passCount++;          // runs for everyone!

// Prefer
if (marks >= 33) {
    cout << "Pass\n";
    passCount++;
}

Most editors (VS Code, Code::Blocks, Dev-C++) can auto-format your file — use it.

3. Initialise every variable

A local variable that is declared but not given a value contains garbage. Reading it is undefined behaviour.

C++
int sum;          // Avoid: garbage value
int sum = 0;      // Prefer
int count{};      // Prefer: brace-initialised to 0

4. Use const wherever a value must not change

const documents intent and lets the compiler stop accidental changes. Use it for fixed values, for function parameters you only read, and for member functions that do not modify the object.

C++
const double PI = 3.14159;

double area(const double radius) {   // radius is read-only here
    return PI * radius * radius;
}

void printReport(const std::string& name) {  // no copy, no change
    std::cout << name << '\n';
}

5. Keep functions small and focused

A function should do one job. If main() is 200 lines long, split it: readMarks(), calculateResult(), printReport(). Small functions are easier to test, reuse and debug. A useful rule: if you need a comment to explain a block inside a function, that block probably wants to be its own function.

6. No magic numbers

C++
// Avoid
if (attendance < 75) { ... }

// Prefer
const int MIN_ATTENDANCE_PERCENT = 75;
if (attendance < MIN_ATTENDANCE_PERCENT) { ... }

Now the rule has a name, and changing it later means changing one line.

7. Prefer std::string and std::vector over raw arrays

Raw C arrays do not know their size and do not check bounds. std::vector grows as needed, knows its size(), and at() checks the index.

C++
#include <vector>
std::vector<int> marks = {78, 91, 66};
marks.push_back(84);
for (int m : marks) std::cout << m << ' ';

Likewise, use std::string instead of char name[20] — no buffer overflows and easy comparison with ==.

8. Let objects manage memory (RAII)

Avoid bare new/delete. If you need a heap object, use a smart pointer; it frees memory automatically when it goes out of scope.

C++
#include <memory>
// Avoid
Student* s = new Student("Aman");
// ... an early return here leaks memory
delete s;

// Prefer
auto s = std::make_unique<Student>("Aman");   // freed automatically

See smart pointers and dynamic memory for details.

9. Pass large objects by const reference

Passing a std::string or std::vector by value copies it. Pass by const& when you only read it, and by & when the function must change it.

C++
double average(const std::vector<int>& marks);   // read only, no copy
void addBonus(std::vector<int>& marks, int bonus); // modifies caller's data

10. Turn on warnings and fix them

Terminal
g++ -std=c++17 -Wall -Wextra -pedantic main.cpp -o main

Warnings such as "unused variable", "comparison of signed and unsigned" or "may be used uninitialised" usually point at real bugs. While testing, add -g -fsanitize=address,undefined to catch out-of-range access at run time.

11–15. Other habits worth building

  • Comment the why, not the what. i++; // increment i adds nothing; // skip header row explains intent.
  • Declare variables close to first use, in the smallest scope possible.
  • Check input. if (!(cin >> age)) { ... } handles a user typing letters instead of a number.
  • **Avoid using namespace std; in header files.** It is acceptable in a small .cpp practice file.
  • Don't repeat yourself. If you copy-paste a block three times, turn it into a function or a loop.

Example: messy code vs clean code

Both programs below compute a student's percentage. The first works, but the second is what a reviewer — or an examiner — wants to see.

C++
#include<iostream>
using namespace std;
int main(){int a,b;cin>>a>>b;
cout<<a*100/b;}
C++
#include <iostream>

int calculatePercentage(int obtained, int maximum) {
    if (maximum <= 0) {
        return 0;                       // avoid division by zero
    }
    return obtained * 100 / maximum;
}

int main() {
    int obtainedMarks = 0;
    int maximumMarks = 0;

    std::cout << "Obtained marks: ";
    std::cin >> obtainedMarks;
    std::cout << "Maximum marks: ";
    std::cin >> maximumMarks;

    std::cout << "Percentage: "
              << calculatePercentage(obtainedMarks, maximumMarks) << "%\n";
    return 0;
}
Obtained marks: 423 Maximum marks: 500 Percentage: 84%

The clean version names everything, guards against a zero divisor, separates calculation from input/output, and is laid out so each step is obvious.

Common mistakes

  • Writing the whole program inside main().
  • Ignoring compiler warnings because "it still runs".
  • Mixing new/delete with manual error handling — and leaking memory on the error path.
  • Comparing int with vector.size() (unsigned) in loops and getting warnings; use std::size_t or a range-based for.
  • Leaving debug cout lines in submitted code.
🏋️ Practice

Take any program you wrote last month. Rename every variable to a meaningful name, split main() into at least three functions, add const where possible and compile with -Wall -Wextra until there are zero warnings.

Summary

  • Clear names and consistent formatting make code readable.
  • Initialise variables, use const, and avoid magic numbers.
  • Keep functions small; pass big objects by const&.
  • Prefer std::vector, std::string and smart pointers over raw arrays and new/delete.
  • Compile with warnings on and treat them as bugs.

Related: structure of a C++ program, comments in C++, C++ interview questions.

Frequently Asked Questions

What are the most important C++ coding best practices for beginners?
Use clear names, indent consistently, keep functions short, mark values that should not change as const, initialise every variable, prefer std::vector/std::string over raw arrays and pointers, and compile with warnings turned on (-Wall -Wextra). These few habits prevent most beginner bugs.
Should I use using namespace std in C++?
In small practice programs and school practicals it is fine inside a .cpp file. Never put it in a header file, because every file that includes the header inherits it and name clashes become likely. In larger projects write std:: or use narrow declarations like using std::cout;.
Why should I avoid raw new and delete in modern C++?
Every new needs exactly one matching delete, and an early return or an exception easily skips it, leaking memory. Containers like std::vector and smart pointers like std::unique_ptr release memory automatically when they go out of scope (RAII), so the leak cannot happen.
What compiler flags help catch mistakes in C++?
With GCC or Clang use -Wall -Wextra -pedantic to see common warnings, and -g with -fsanitize=address,undefined while testing to catch out-of-bounds access and undefined behaviour at run time. Treat warnings as errors to fix, not noise.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicif, else-if and else Statements Your progress: 14 / 81 (17%) · Lesson 15 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free