Stop Writing C++ the C Way! 10 Examples to Upgrade to Modern C++!

Many students actually write C++ in the style of C. For example, using <span><span>printf</span></span>, frequently using global variables, and starting array indices from 1… These coding practices may run, but they are neither safe nor modern.

It is important to know that while C++ is compatible with many features of the C language, modern C++ has provided more advanced, safer, and more efficient ways and tools. Learning these new features will not only make your code more elegant and readable but also significantly improve performance and stability.

Today, we will look at 10 common C-style coding practices and show you how to upgrade them to modern C++, allowing your code to truly transform.

1️⃣ Input and Output Methods

Using C-style printf and scanf for input and output operations, while powerful, lacks type safety. Modern C++ provides the iostream library, which is not only type-safe but also supports chaining and user-defined types for input and output.C Style

#include <stdio.h>
int main() {
    int x;
    scanf("%d", &x);
    printf("Hello %d\n", x);
    return 0;
}

✅ Modern C++

#include <iostream>
int main() {
    int x;
    std::cin >> x;
    std::cout << "Hello " << x << std::endl;
    return 0;
}

2️⃣ Defining ConstantsIn C, we typically use #define to define constants, but it lacks type checking. Modern C++ provides the constexpr keyword, which allows defining typed constants and supports compile-time calculations.C Style

#define PI 3.14159

✅ Modern C++

constexpr double PI = 3.14159;

3️⃣ Arrays and ContainersC-style arrays have a fixed size, which can lead to buffer overflow issues. Modern C++ provides the standard library container std::vector, which supports dynamic sizing, automatic memory management, and can utilize range-based for loops and other STL features.C Style

int a[10000];

✅ Modern C++

#include <vector>
std::vector<int> a(10000); // A vector of integers with size 10000

4️⃣ Array Indices Starting from 1In C-style code, you may sometimes see array indices starting from 1, which is inconsistent with the STL container style in modern C++, leading to offset errors. Modern C++ recommends starting from 0.C Style

for (int i = 1; i <= n; ++i) {
    std::cout << a[i] << ' ';
}

✅ Modern C++

for (int i = 0; i < n; ++i) {
    std::cout << a[i] << ' ';
}

5️⃣ Misuse of Global VariablesGlobal variables reduce the modularity and maintainability of code and increase coupling. Modern C++ recommends using local variables instead of global variables to reduce naming conflicts and facilitate maintenance.❌ C Style

int a[1000000];  // Global array

✅ Modern C++

#include <vector>
int main() {
    std::vector<int> a(1000000); // Smaller scope, reduces naming conflicts
    return 0;
}

6️⃣ String HandlingC-style string handling functions like gets can easily lead to buffer overflows. Modern C++ provides the std::string class, which automatically manages memory, preventing overflows and is easy to use.❌ C Style

char str[100];
gets(str);  // Very prone to buffer overflow

✅ Modern C++

#include <iostream>
#include <string>
std::string str;
std::getline(std::cin, str);

7️⃣ Manual Swap FunctionManually writing a swap function is not only verbose but also prone to errors. Modern C++ provides the std::swap function in the standard library, which is implemented as a template, supporting various types, making it concise and efficient.❌ C Style

int t = a;  // Swap integer variable a with b
a = b;
b = t;

✅ Modern C++

#include <utility>
std::swap(a, b);  // Template function, supports swapping different types of variables

8️⃣ Traditional For Loop TraversalTraditional for loop traversal is error-prone, especially when handling indices. Modern C++ provides range-based for loops, making container traversal simpler and safer.❌ C Style

for (int i = 0; i < n; ++i) {
    std::cout << a[i] << ' '; // Need to be cautious of index i's range
}

✅ Modern C++

for (auto x : a) {
    std::cout << x << ' '; // No need to worry about index out of bounds
}

9️⃣ Verbose Type DeclarationsIn C++, explicit type declarations can sometimes be verbose. Modern C++ provides the auto keyword, allowing the compiler to automatically deduce the variable type, making the code more concise.❌ C Style

std::vector<int>::iterator it = v.begin();

✅ Modern C++

auto it = v.begin();

🔟 Initialization MethodsC-style initialization methods can sometimes lead to narrowing conversion errors. Modern C++ provides uniform initialization syntax, which can prevent such errors.❌ C Style

int x = 4.2;  // Compiles successfully, x's value is 4 (narrow conversion)

✅ Modern C++

int x{4.2};  // Compilation error (uniform initialization syntax prevents narrowing conversion at compile time)

ConclusionModern C++ is not just a syntax upgrade, but a shift in thinking. By adopting the features and best practices of modern C++, the quality and maintainability of your code will be significantly improved. Start with these 10 points to make your C++ code more modern and professional.If you find this article helpful, feel free to like, share, and bookmark, supporting us to continue creating! Every interaction from you is our motivation to move forward. You are also welcome to share other “C-style” practices you have seen in the comments section, so we can all exchange ideas!

This article is originally published by LAMBDA Programming and AI. Please indicate the source when reprinting.

Leave a Comment