The C++ programming language was developed long before Agile software development came into vogue, yet the Agile principles were followed even before they were formalized in the Manifesto for Agile Software Development. Two of the Agile principles are simplicity and the ability to meet changing requirements. In this article we shall discuss how C++ fulfills these and other Agile software development principles through its language features.


Modern C++

C++ is a continuously evolving language. The C++ guidelines have set an objective to provide a “modern C++,” asking, “What would you like your code to look like in 5 years’ time, given that you can start now? In 10 years’ time?” The goals of the guidelines are to facilitate users/developers to write simpler, more efficient, and more maintainable code. All the goals are aligned with the Agile principles.

Compatible with C

As C++ is evolved from C to be usable as a high level programming language, it has been one of the objectives to keep C++ compatible with C so that developers from an early era are able to develop with both C and C++. C++ is more expressive, and has better type checking, but C code could still be encapsulated within C++. You can call C from C++, and vice versa. A common subset of C and C++ lets a developer compile the C-C++ code with a C++ compiler.

Dynamic Memory Management

The standard library provides the different sub-libraries that are used in standard C++. The classes and functions in these libraries support Agile principles. Object memory that needs to be explicitly freed when an object is not used anymore is not so Agile. The memory management library provides smart pointers for dynamic memory management. The std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of the object when the unique_ptr goes out of scope. Smart pointers prevent resource leaks.

An example to illustrate the use of a unique pointer is as follows:

#include <iostream>
#include <memory>

int main () {

std::unique_ptr<int> e;

std::unique_ptr<int> a (new int);
std::unique_ptr<int> b (new int (10));

*a = *b * 2;

std::cout << “*a: ” << *a << ‘\n’;
std::cout << “*b: ” << *b<< ‘\n’;
return 0;

}

The output is:

*a: 20
*b: 10

A std::shared_ptr is a smart pointer that has a shared ownership of an object, which implies that multiple such pointers may own the same object. Because the object is shared, its associated memory is freed only when all the shared pointers to the object go out of scope. The following example illustrates two different approaches to creating a shared pointer:

#include <iostream>
#include <memory>

int main () {

std::shared_ptr<int> sp1 = std::make_shared<int> (10);

std::shared_ptr<int> sp2 (new int(10));

std::cout << “*sp1: ” << *sp1 << ‘\n’;
std::cout << “*sp2: ” << *sp2 << ‘\n’;

return 0;

}

The output is:

*sp1: 10
*sp2: 10

Guidelines Support Library

One of the objectives of C++ is to make the language less prone to error, and that includes catching programming logic errors. C++ promotes a statically type-safe codebase. A set of library components, or extensions, are provided to catch error prone code early in development. The core guidelines support library is provided in the gsl namespace.

Naming and Layout Style

C++ promotes consistent naming and layout style for readability. Some of these naming and programming style guidelines are discussed next. Comments, while useful, are not a substitute for code. If something is better said in code, use code, which is more precise than comments and is actually read by a C++ compiler. Code provides the implementation while comments state the intent of the code.

Comments are expected to be not too verbose. A consistent indentation style that adds an indent after the start of a loop, or conditional statement such as for, while, and if is recommended. Class, interface, function and variable names should be readable with a hint of the functionality provided, and not supposed to include detailed information such as type information.

Variable name length should be consistent with its scope; as an example, naming a global variable with a single letter does not quite convey the scope of the variable, or making a local variable verbose by including multiple underscores over-conveys the variable’s scope. All-caps should be reserved for macros only. Most of all, literals should be readable and preferably convey a meaning if relevant, and some ways to achieve that are by using underscores and literal suffixes. Spaces should be used sparingly. Class member declarations follow a conventional order:

  1. first the types, which includes classes and enums;
  2. and next come the constructors;
  3. followed by functions;
  4. and lastly the data.

Other recommendations include placing separate statements on separate lines, declaring one name per declaration, using .cpp file suffix for code files, and .h file suffix for interfaces.

Object Oriented

C++ is an object oriented programming language and follows the familiar principles of object-orientedness including inheritance, encapsulation, and polymorphism. C++ provides classes and structs for user-defined types that group related data into structures. Use the class keyword if the data structure is invariant, and use the struct keyword if the data members can vary independently. Class hierarchies can be used to group related classes into a hierarchy. The class C++ provides enumerations for defining a set of values and types for such sets of values.

Flexibility with Templates

Agile software development depends on flexibility, and C++ supports the generic programming model in which algorithms are parameterized by types that can be supplied at the time of initialization. C++ provides templates to develop such algorithms that can apply to several different types.

Resource Management

C++ provides several features for resource management including smart pointers, which are discussed earlier. C++ provides resource acquire/release function pairs such as fopen/fclose. Calls to these paired functions can be encapsulated in an object for easier resource management. To avoid a resource leak, an object created with new should be assigned to a resource handle rather than a plain pointer. Non-owning pointers, such as a raw pointer, are discouraged in favor of smart pointers, which are owning and managing resources automatically.


Exception Handling

For exception handling C++ provides the try-catch paradigm commonly used in object-oriented languages. To meet changing requirements in software development, C++ provides two specifications to limit the types of exceptions a function can throw. The dynamic exception specification can be used to list the exceptions a function might possibly throw. The noexcept specification provides the noexcept specifier for when a function cannot throw an exception.





Source link

By i53gf