Lesson 24 / 25
Modern C++ Guidelines
Follow the core guidelines that make C++ safer and clearer.
A safer subset of a powerful language
C++ is large, and much of its safety comes from choosing a good subset. The C++ Core Guidelines, edited by Bjarne Stroustrup and Herb Sutter, collect advice such as: prefer RAII and avoid naked new/delete; use std::vector, std::array and std::string instead of raw arrays and C strings; pass small types by value and large inputs by const&; return values rather than out-parameters; use smart pointers to express ownership and raw pointers or references only for non-owning access; prefer enum class, constexpr and nullptr; mark functions const, noexcept and [[nodiscard]] where appropriate; make single-argument constructors explicit; follow the rule of zero; use std::optional, std::variant, std::span and std::string_view for clear interfaces; prefer standard algorithms and ranges over raw loops; and avoid casts, especially C-style casts, using static_cast and friends when needed. Tools such as clang-tidy check many of these rules automatically. The C++ community is also working on stronger safety features and profiles in future standards; in the meantime, these habits remove most memory-safety bugs.
Old style versus modern style
The same task with fewer ways to fail.
// old style
char* copy_name(const char* src) {
char* dst = (char*)malloc(strlen(src) + 1); // C cast, manual memory, may be NULL
strcpy(dst, src); // caller must remember free()
return dst;
}
int* make_scores(int n) { return new int[n]; } // who deletes this, and with delete[]?
// modern style
#include <string>
#include <string_view>
#include <vector>
std::string copy_name(std::string_view src) { return std::string{src}; } // owns its memory
std::vector<int> make_scores(std::size_t n) { return std::vector<int>(n); } // freed automatically
// clang-tidy can flag the old patterns:
// clang-tidy main.cpp -checks='cppcoreguidelines-*,modernize-*,bugprone-*' -- -std=c++20Turn on clang-tidy
Running clang-tidy with modernize-*, bugprone-* and cppcoreguidelines-* checks in your editor teaches modern idioms as you type and catches many classic mistakes.
Quick check: According to modern C++ guidelines, how should ownership of a heap object usually be expressed?
- A smart pointer such as std::unique_ptr
- A raw pointer with a comment
- A global variable
- A C-style cast
Answer
A smart pointer such as std::unique_ptr — Smart pointers make ownership explicit and release resources automatically.