C++
C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significantly over time, and modern C++ now has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation. It is almost always implemented as a compiled language, and many vendors provide C++ compilers, including the Free Software Foundation, LLVM, Microsoft, Intel, Oracle, and IBM, so it is available on many platforms.
Compiler
The C++ language is standardized by the International Organization for Standardization (ISO) and the latest standard version is C++20. The most widely used compiler is GCC, which is the default compiler on most Linux distributions. The Clang compiler is also popular, and it is the default compiler on macOS. The MSVC compiler is the default compiler on Windows, and it is also available on Linux and macOS.
In this course, we will be using Clang as the compiler. To install Clang on the RPi, run the following command:
sudo apt update
sudo apt install clang
CMake
CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. Because CMake generates native makefiles and workspaces, you can open the project in your preferred development environment and compiler.
To install CMake on the RPi, run the following command:
sudo apt update
sudo apt install cmake
cpp-intro
Project
The cpp-intro
project is a simple C++ project that can be used as a template for your own projects.
We will be using this project to demonstrate how to use CMake to build a C++ project.
First fork the repository, and clone it in the RPi:
cd ~ # go to home directory
git clone REPO_URL # replace REPO_URL with your forked repository URL
You should now have a cpp-intro
directory in your home directory.
Let's go into the directory and build the project:
cd cpp-intro # go into the directory
mkdir build # create a build directory
cd build # go into the build directory
cmake .. # generate the build files
cmake --build . # build the project
A good practice is to separate the source code from the build files.
This way, you can easily delete the build files without affecting the source code.
This is why we created a build
directory and ran cmake ..
inside the directory.
VSCode has extensions that can help you build and debug C++ projects. C/C++ Extension Pack is a good extension pack that includes the C/C++ extension and other useful extensions.
In the build
directory, you should see a MyExecutable
executable.
You can run the executable by running ./MyExecutable
while in the build
directory.
cpp-intro
Project Structure
Go ahead an open the cpp-intro
project in VSCode.
In the terminal, you can run code .
to open the current directory in VSCode.
You should see the following files and directories:
build/
.gitignore
CMakeLists.txt
main.cpp
Here:
- The
build
directory is where the build files are generated. - The
.gitignore
file tells Git to ignore certain files and directories. - The
CMakeLists.txt
file is the CMake configuration file. - The
main.cpp
file is the source code of the project.
CMakeLists.txt
File
The CMakeLists.txt
file is the CMake configuration file.
It tells CMake how to build the project.
Let's take a look at the CMakeLists.txt
file in the cpp-intro
project:
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(MyExecutable main.cpp)
Here:
- The first two lines tell CMake the minimum version of CMake required and the name and version of the project.
- The next two lines tell CMake to use C++17 and that C++17 is required.
- The last line tells CMake to build an executable called
MyExecutable
from themain.cpp
file.
- Change the project name to
MyFirstProject
. - Change the project version to
0.1
. - Change the executable name to
MyFirstExecutable
. - Show your TA that you can build the
cpp-intro
project.
main.cpp
File
The main.cpp
file is the source code of the project.
Let's take a look at the main.cpp
file in the cpp-intro
project:
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
int x = 5;
int y = 7;
std::cout << "The sum of " << x << " and " << y << " is " << x + y << std::endl;
return 0;
}
Here:
- The first line tells the compiler to include the
iostream
header file. - The
main
function is the entry point of the program. - The
std::cout
object is used to print to the console. - The
std::endl
object is used to print a new line.
- Modify the
main.cpp
file to print your name and classroom. - Create a new variable called
z
and print the sum ofx
,y
, andz
. - Create a new variable called
w
and print the product ofx
,y
,z
, andw
. - Create a new variable called
v
and print the division ofx
,y
andv
. - Show your TA that you can build and run the
cpp-intro
project.
Functions
A function is a block of code that performs a specific task. A function can be called from anywhere in the program. A function can optionally take parameters and return a value.
// function declaration
int add(int x, int y);
// function definition
int add(int x, int y)
{
return x + y;
}
int main()
{
int x = 5;
int y = 7;
int z = add(x, y); // call the add function
std::cout << "The sum of " << x << " and " << y << " is " << z << std::endl;
return 0;
}
Here:
- The
add
function takes two parametersx
andy
and returns the sum of the two parameters. - The
add
function is called from themain
function.
-
The
add
function is declared before themain
function. This is because theadd
function is called from themain
function. -
Usually, the function declaration is put in a header file and the function definition is put in a source file.
- Write the following functions:
int subtract(int x, int y)
that returns the difference ofx
andy
.int multiply(int x, int y)
that returns the product ofx
andy
.int divide(int x, int y)
that returns the division ofx
andy
.
- Show your TA that you can build and run the
cpp-intro
project.
Classes
A class is a user-defined data type that contains data members and member functions. A class is a blueprint for creating objects. An object is an instance of a class. A class can be used to create many objects.
class Rectangle
{
public:
int width;
int height;
int area()
{
return width * height;
}
};
Here:
- The
Rectangle
class has two data memberswidth
andheight
. - The
Rectangle
class has one member functionarea
that returns the area of the rectangle.
- Write a
Circle
class that has aradius
data member and anarea
member function that returns the area of the circle. - Create an instance of the
Circle
class and print the area of the circle. - Show your TA that you can build and run the
cpp-intro
project.
References
A reference is an alias for an existing variable.
A reference is declared by putting an ampersand (&
) after the type of the variable.
int x = 5;
int &y = x; // y is a reference to x
Here:
- The
y
variable is a reference to thex
variable. - The
y
variable is an alias for thex
variable.
Practice Problems
Problem 1
Write a Point
class that has x
and y
data members (double
) and a distance_to_origin
member function that returns the distance between the point and the origin.
Problem 2
Augment the Point
class with a distance_to_point
member function that takes a Point
object as a parameter and returns the distance between the two points.
Problem 3
Write a Line
class that has p1
and p2
data members(Point
) and a length
member function that returns the length of the line.
Problem 4
Augment the Line
class with a distance_to_point
member function that takes a Point
object as a parameter and returns the distance between the line and the point.
Problem 5
Skip this problem!
Augment the Point
class with a distance_to_line
member function that takes a Line
object as a parameter and returns the distance between the point and the line.
Problem 6
Create a Triangle
class that has p1
, p2
, and p3
data members and a area
member function that returns the area of the triangle.
p1
, p2
, and p3
are the three vertices (Point
) of the triangle.
Problem 7
Let a Polygon
class be a class that has a std::vector<Point>
data member and a area
member function that returns the area of the convex polygon.
The std::vector<Point>
data member is a vector of Point
objects that represent the vertices of the polygon (in order).
Write a Polygon
class that has a std::vector<Point>
data member and a area
member function that returns the area of the polygon.
Problem 8
Augment the Polygon
class with a perimeter
member function that returns the perimeter of the polygon.
Problem 9
Create a AUV
class that represents an autonomous underwater vehicle.
The AUV
class should have the following data members:
name
(std::string
)position
(Point
)depth
(double
)heading
(double
)speed
(array<double>
) where the first element is the forward speed, the second element is the lateral speed, and the third element is the vertical speed.angular_speed
(double
)
The AUV
class should have the following member functions:
step
that takes adouble
parameterdt
and moves theAUV
using velocities.apply_accleration
that takes anarray<double>
of size 3 and accelerates theAUV
by the given acceleration, anddt
the time step. The first element of the array is the forward acceleration, the second element is the lateral acceleration, and the third element is the vertical acceleration.apply_angular_accleration
that takes adouble
parameterangular_acceleration
, and the time stepdt
and accelerates theAUV
by the given angular acceleration.
Problem 10
In C++, header files are used to declare classes and functions, and source files are used to define classes and functions.
Let's create a Point
class in a header file and a source file.
Create a new file called Point.hpp
and put the following code in the file:
#pragma once
class Point
{
private:
double m_d_x;
double m_d_y;
public:
Point(double x, double y);
double x(){ return m_d_x; }
double y(){ return m_d_y; }
double distance_to_origin();
double distance_to_point(Point p);
};
Here:
- The
Point
class is declared in thePoint.hpp
file. - The
Point
class has two private data membersx
andy
. - The
Point
class has a public constructor that takes twodouble
parametersx
andy
. - The
Point
class has a publicx
member function that returns thex
data member. - The
Point
class has a publicy
member function that returns they
data member. - The
Point
class has a publicdistance_to_origin
member function that returns the distance between the point and the origin. - The
Point
class has a publicdistance_to_point
member function that takes aPoint
object as a parameter and returns the distance between the point and the given point. - The
#pragma once
directive tells the compiler to include the header file only once.
Including the header file more than once will cause a compilation error.
This is because the compiler will see two declarations of the Point
class.
The #pragma once
directive tells the compiler to include the header file only once.
Therefore, even if the header file is included more than once, the compiler will only see one declaration of the Point
class.
Create a new file called Point.cpp
and put the following code in the file:
#include "Point.hpp"
#include <cmath>
Point::Point(double x, double y)
{
this->m_d_x = x;
this->m_d_y = y;
}
double Point::distance_to_origin()
{
return std::sqrt(std::pow(m_d_x, 2) + std::pow(m_d_y, 2));
}
double Point::distance_to_point(Point p)
{
return std::sqrt(std::pow(m_d_x - p.x(), 2) + std::pow(m_d_y - p.y(), 2));
}
Here:
- The
Point
class is defined in thePoint.cpp
file. - The
Point
class constructor is defined. - The
Point
classdistance_to_origin
member function is defined. - The
Point
classdistance_to_point
member function is defined.
Your directory structure should look like this:
build/
.gitignore
CMakeLists.txt
main.cpp
Point.hpp
Point.cpp
In main.cpp
, you can include the Point.hpp
header file and use the Point
class:
#include <iostream>
#include "Point.hpp"
[...]
Notice that we used double quotes ("
) instead of angle brackets (<
and >
).
This is because the Point.hpp
file is in the same directory as the main.cpp
file.
Now, you should also remove the Point
class from the main.cpp
file.
Go ahead and build the project:
cmake --build . # build the project. You should be in the build directory.
The build system should be able to find the Point.hpp
and compile.
However, the build system will not be able to find the Point.cpp
file.
Therefore, you should see an error message like this:
[...]
[ 50%] Building CXX object CMakeFiles/MyExecutable.dir/main.cpp.o
[100%] Linking CXX executable MyExecutable
CMakeFiles/MyExecutable.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x1c): undefined reference to `Point::Point(double, double)'
[...]
This is because we did not tell the build system to compile the Point.cpp
file.
Let's go ahead and tell the build system to compile the Point.cpp
file.
Open the CMakeLists.txt
file and add Point.cpp
to the following line:
add_executable(MyFirstExecutable
main.cpp
Point.cpp
)
Notice that we did not include Point.hpp
in the add_executable
command.
This is because Point.hpp
is included in main.cpp
.
Now, go ahead and build the project again:
cmake --build . # build the project. You should be in the build directory.
You should now be able to build the project successfully. Go ahead and run the executable:
./MyFirstExecutable
Everything should work as before.
- Create a
Line
class in a header file and a source file. - Create a
Triangle
class in a header file and a source file. - Create a
Polygon
class in a header file and a source file. - Create a
AUV
class in a header file and a source file. - Show your TA that you can build and run the
cpp-intro
project.