C++
Introduction
My favo(u)rite program C++ is not one of the easiest language to master.
Let me start with one of the most not understood parts.
- Pointer, Value and Addresses.
- Parsing variables and Calling by Value, by Pointer and by Reference.
- Char and Strings
Pointers, Values and Addresses
| Usage | Coding | Output |
|---|---|---|
|
For a C++ program, the memory of a computer is like a succession of memory cells, each one byte in size, and each with a unique address.
The address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&), known as address-of operator.
foo = &myvar; assigns the address of variable myvar to foo; by preceding the name of the variable myvar with the address-of operator (&), we are no longer assigning the content of the variable itself to foo, but its address. |
// my first pointer
#include <iostream>
using namespace std;
int main () {
int firstvalue, secondvalue;
int * mypointer;
mypointer = &firstvalue;
*mypointer = 10;
mypointer = &secondvalue;
*mypointer = 20;
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';
return 0;
}
|
firstvalue is 10 secondvalue is 20 |
Parsing
The examples are taken from Geeks for Geeks, C++ pointers and other pages on that website.
Passing by Value
| Usage | Coding | Output |
|---|---|---|
|
Call by value is used in certain conditions like:
|
// C++ Program to implement
// Swapping using Call by function
#include <iostream>
using namespace std;
// Swap function to demonstrate
// call by value method
void swap(int x, int y)
{
int t = x;
x = y;
y = t;
cout << "After Swapping in function x: " << x
<< ", y: " << y << endl;
}
// Driver Code
int main()
{
int x = 1, y = 2;
cout << "Before Swapping: ";
cout << "x: " << x << ", y: " << y << endl;
swap(x, y);
cout << "After Swapping: ";
cout << "x: " << x << ", y: " << y << endl;
return 0;
}
|
The output: Before Swapping: x: 1, y: 2 After Swapping in function x:2, y:1 After Swapping: x: 1, y: 2 |
Passing by Pointer
| Usage | Coding | Output |
|---|---|---|
|
Here, the memory location (address) of the variables is passed to the parameters in the function, and then the operations are performed. It is also called the call by pointer method. |
// C++ program to swap two numbers using
// pass by pointer
#include <iostream>
using namespace std;
void swap(int *x, int *y)
{
int z = *x;
*x = *y;
*y = z;
}
// Driver Code
int main()
{
int a = 45, b = 35;
cout << "Before Swap\n";
cout << "a = " << a << " b = " << b << "\n";
swap(&a, &b);
cout << "After Swap with pass by pointer\n";
cout << "a = " << a << " b = " << b << "\n";
}
|
Before Swap a = 45 b = 35 After Swap with pass by pointer a = 35 b = 45 |
Passing by Reference
| Usage | Coding | Output |
|---|---|---|
|
It allows a function to modify a variable without having to create a copy of it. We have to declare reference variables. The memory location of the passed variable and parameter is the same and therefore, any change to the parameter reflects in the variable as well. |
// C++ program to swap two numbers using
// pass by reference
#include <iostream>
using namespace std;
void swap(int& x, int& y)
{
int z = x;
x = y;
y = z;
}
int main()
{
int a = 45, b = 35;
cout << "Before Swap\n";
cout << "a = " << a << " b = " << b << "\n";
swap(a, b);
cout << "After Swap with pass by reference\n";
cout << "a = " << a << " b = " << b << "\n";
}
|
Before Swap a = 45 b = 35 After Swap with pass by reference a = 35 b = 45 |
Pass by Pointer vs Pass by Reference
Knowing the differences between passing by pointer and passing by reference is crucial for effective function design.
The following table lists the major differences between the pass-by-pointer and pass-by-reference methods.
| Parameters | Pass by Pointer | Pass by Reference |
|---|---|---|
| Passing Arguments | We pass the address of arguments in the function call. | We pass the arguments in the function call. |
| Accessing Values | The value of the arguments is accessed via the dereferencing operator * | The reference name can be used to implicitly reference a value. |
| Reassignment | Passed parameters can be moved/reassigned to a different memory location. | Parameters can’t be moved/reassigned to another memory address. |
| Allowed Values | Pointers can contain a NULL value, so a passed argument may point to a NULL or even a garbage value. | References cannot contain a NULL value, so it is guaranteed to have some value. |
Strings
In C++, we can store the sequence of characters i.e. string in two ways:
- either as a char array.
- either as a std::string object.
In this paragraph, we will discuss some major differences between string and char[] in C++.
| char str[14] = "GeeksforGeeks" | string str("GfG is best"); |
|---|---|
// C++ Program to show the use of character array type strings
#include <iostream>
using namespace std;
int main()
{
// Character array
char str[14] = "GeeksforGeeks";
// Print each character in the array
for (int i = 0; i < 13; i++) {
cout << str[i];
}
return 0;
}
|
// C++ Program to show the use of std::string
#include <iostream>
using namespace std;
int main()
{
// Sample string
string str("GFG is best");
// Print the string
cout << str;
return 0;
}
|
Of course there are ways to convert one with the other.
But the usage can be rather strange for the beginner.
Online Reference
- CppReference, Standard for modern C++ documentation
- Up-to-date (C++11 t/m C++23)
- Complete, all standard libraries and Language elements.
- Good explanation.
- Modernes Cpp, Blog and tutorials around Modern C++.
- Clear explanation of modern features such as auto, constexpr, concepts, ranges, coroutines, etc.
- Focused on practical use of modern C++.
- Ideal for: C++ developers who already have some experience, but want to learn modern idioms.
- CppInsights.io, Live visualisation of C++-code
- Beginner and intermediate friendly.
- Recently updated for C++17/C++20.
- Clearly structured explanations with examples.
- Recommended if you want to refresh your C++ skills with explanations rather than dry documentation.
- GodBolt.org, Learningplatform for C++ (include Modern C++).
- You can test C++ code and directly compare assembler output or other compilers.
- Combine with cppreference to try out features directly.
- Definitely do this for template debugging or performance tuning.
STL Container Maps & Sets
The C++ standard library (STL) offers more containers than vector and list.
| STL container | Map & sets | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| But what is a container?
|
| ||||||||||||||||||||||||||||
| Maps | Sets |
|---|---|
Maps are associative list, meaning a key, value pair.
Syntaxmap<label_key,key_value> var_name
Examplesmap<string, int> words; Loop for pairs |
Sets in C++ are containers that store unique elements in a sorted manner. The elements inside the set cannot be changed, once they are added to the set, they can only be inserted or deleted. They are implemented as BST (Binary Search Trees) in memory. Set is present in #include<set> header file. The elements inside the set can be accessed using iterators. Syntaxset <data_type> name = {initial_values};
Note: By default the set stores values in non-decreasing order. To store the values in non-increasing order, we use an inbuilt comparator function set <data_type, greater <data_type>> name; Examplesset <int> s; //initializes a set of size 0 which stores integer values arranged in non-decreasing order
set <int> s = {10, 20, 30}; //initializes a set having initial values as 10,20,30
set <int, greater <int>> s; //initializes a set of size 0 which stores integer values arranged in non-increasing order
|
Iterator
| Name | Description |
|---|---|
| input iterator | Can iterate forward using ++ and read element values using *. This is the kind of iterator that istream offers; (BS - §20.6.4).
If (*p).m is valid, p−>m can be used as a shorthand. |
| output iterator | Can iterate forward using ++ and write element values using *. This is the kind of iterator that ostream offers; (BS - 20.6.4). |
| forward iterator | An input iterator that can iterate repeatedly over a sequence and repeatedly read from or write to an element. This is the kind of iterator that forward_list offers §20.6 |
| bidirectional iterator | A bidirectional iterator that can move forward and backwards n positions using +=n, +, −=n, and −. |
| contiguous iterator | A random-access iterator where the elements are allocated contiguously. This is the kind of iterator that vector offers. |
From the operations offered, we can see that wherever we can use an output iterator or an input iterator, we can use a forward iterator. A bidirectional iterator is also a forward iterator, and a random-access iterator is also a bidirectional iterator. |}
Class Rules
Rule of Three
The Rule of Three [1][2] says that there are three member functions that go together:
- the destructor,
- the copy constructor, and
- the assignment operator.
A class that defines a destructor should almost always define the other two members.
Moreover, a class that defines a copy constructor or assignment operator should usually define the other two members as well [3].
Rule of Five
The rule of thumb [4] (also known as the Rule of Five) for class special member functions is that if you explicitly define
- any
- copy constructor,
- move constructor,
- copy assignment operator,
- move assignment operator, or
- destructor,
then
- you must either explicitly define or default all of them.
Bancila, Marius. Modern C++ Programming Cookbook: Master Modern C++ with comprehensive solutions for C++23 and all previous standards (p. 159). (Function). Kindle Edition.
Rule of Zero
Opposed to the Rule of Five [4] on the one hand but complementing it on the other is the so-called Rule of Zero.
This rule states that unless a class deals with ownership of resources, it should have no custom destructors, copy and move constructors, and, respectively, copy and move assignment operators.
See also
- Developer Apple Docs, Overview of Dynamic libraries.
RAII
- Stroustrup, Why does C++ does not have a finally. Well, because of RAII.
- SonarSource Blog, What are the Rules of Three, Five and Zero in C++?
- Wikipedia, RAII - Resource Acquisition Is Initialization.
Reference
- ↑ DrDobbs, C-made-easier, the Rule of Three.
- ↑ Marshall Cline coined the term in 1991.
- ↑ Classes often have an empty virtual destructor, which is there only because it is virtual and not to do any actual work. Such destructors don’t count for the purpose of this discussion.
- ↑ 4.0 4.1 Bancila, Marius. Modern C++ Programming Cookbook: Master Modern C++ with comprehensive solutions for C++23 and all previous standards