The C++ Project includes some examples and notes (mostly C++11). It also contains additional examples/notes from the C++ How to Program (9th Edition) book.
Notes
- The
mainfunction is the designated start for program execution. All C++ programs must have a main function. If you try to compile a C++ program without a main function, the compiler raises an error. It can't be overloaded or declared aninlineorstaticfunction. Also, it can't have its address taken, and can't be called from your program. It can be declared in different forms:int main() {...}which runs independently of environment-provided arguments.int main(int argc, char *argv[]) {...}which accepts environment provided arguments:argc (Argument Count)argument is a non-negative integer that contains the count of arguments that follow inargv[]argv[] (Argument Vector)argument is an array of null-terminated strings representing command-line arguments entered by the user of the program. By convention,argv[0]is the command with which the program is invoked. So,argv[0]displays the program filename.argv[1]is the first command-line argument. The last argument from the command line isargv[argc - 1], andargv[argc]is always NULL.- The size of the array pointed to by
argvis at leastargc + 1, and the last element,argv[argc], is guaranteed to be a NULL pointer:
int main(/* implementation-defined */) {...}which accepts implementation-defined type parameters. The C++ standards recommend implementation-defined main functions to place the extra (optional) parameters afterargvargument.
endlmanipulator inserts a newline and flushes the stream.- Header files shouldn't include namespaces.
- unsigned keyword allows the variable to be only a positive. The integer can never be a negative value.
default_random_engine-srandfunctions change the seed(starting point) of the random number generator algorithm.float (4),long (4),double (8),long double (8)- Stack: LIFO, Queue: FIFO.
- The ampersand(&) is used in variable declarations to declare reference variable.
- Overloaded Function: Function overloading is a feature of OOP where the multiple functions with the same name has different parameter data types.
- Temporary is a construct that generates an ordinary type or function at compile time based on arguments the user supplies for the template parameters. They are described as
template <typename T>ortemplate<class T>.typenameandclasskeywords can be used interchangeably. - Performance Concern: If the performance is important, then better to avoid using recursion functions. It takes more time and uses more memory. The deeper the recursion, the more memory is used. Because each recursive call requires its own stack frame to store variables and other information.
vector.insert()andvector.emplaceare used for the same purpose. However;emplaceconstructs an object in place at a specified position, potentially avoiding a copy operation.insertadds a copy of the object at the specified position.
std::vector::beginreturns a read/write iterator that points to the first element in the vector.std::vector::endreturns a read/write iterator that points to the last element in the vector.std::vector::cbeginreturns a read-only iterator that points to the first element in the vector.std::vector::crendreturns a read-only reverse iterator that pointsto one before the first element in the vector.std::vector::crbeginreturns a read-only reverse iterator that points to the last element in the vector.std::vector::cendreturns a read-only iterator that points to the last element in the vector.- It is important to set a default value like
nullptrto the pointers. It might cause critical issues to update a pointer that doesn't have a default value since the value might not point to a valid memory location. lvaluesimply means an object that has an identifiable location in memory.r-valuesimply means, an object that has no identifiable location in memory.chararray constants have a static storage duration (they exist throughout the program).- The
~operator is used to reverse operation on the bytes so it makes sense to use it fordestructorfunction definitions like~Destroy() - When a variable is declared as
static, space for it gets allocated for the lifetime of the program. The space for the static variable is allocated only once. - A
staticvariable of a class, gets allocated once so it stores one value for each generated same type class. So, it isn't used to store special values for each class. It stores the class specific global variables. - The
staticvariable can't be defined withconstsinceconstkeyword means that it can't change the objects in the function/class in which it is defined. However, thestaticvariables are independent of the class objects - Objects are created from the inside out and destroyed from the outside in via
destructorfunctions. - The
friendclass/function can access private and protected members of a class. The parameter object that references the class must be a constant.friendfunctions in the class have permission to access any property(public/protected/private) of the class which it is definedfriendclass have permission to access public/private/protected members of other classes in which it is declared as a friend
- Using
this->is same with(*this).. Because the dot(.) operator is prioritized higher than the asterisk(*) operator, it is necessary to use parentheses. - The operators can be overloaded to customize some functionalities. It is like overloading the
<<operator to print a text specifically by the class requirements or the++operator to update a character in the text instead of increasing the number. structkeyword allows us to create structures. Structures are a way to group several related variables into one place like an object and can contain different data types:struct str { int num; string text; ... }
- A memory leak occurs when new memory is allocated dynamically and never deallocated. In
Cprograms, new memory is allocated by themallocorcallocfunctions, and deallocated by thefreefunction. In C++, new memory is usually allocated by thenewoperator and deallocated by thedeleteor thedelete []operator. The list variables should be deallocated by thedelete []since it guarantees to call all of the elements in the list. Similarly, usedeleteto deallocate the memory that is defined as a single element. Usingdelete []to deallocate the single memorized element is undefined. friendfunctions can't be inherited in C++. If the base class has any friend function, this function doesn’t become the friend of the derived class.Polymorphismmeans having multiple forms. To adaptpolymorphismin inherited classes,overridean inherited function in the derived class by defining a function with the same prototype of the overridden function and usingoverridekeyword.- When declaring a function with
overridekeyword, the compiler checks whether the base class has the same function that has the same signature(same name, parameters). If it doesn't exist, then the compiler shows error. Also, the base class must be declared as avirtualfunction to enable dynamic overriding. virtualfunctions cannot bestaticbut can be afriendfunction of another class. Also, the constructors can't be defined asvirtualcause virtual pointer doesn't define when the constructor of the class is executed.- About the difference between
virtualandabstractfunctions, thevirtualfunction must have a base functionality(body) so, it provides the derived classes with the option of overriding it. However, this is not mandatory. When it is not overridden, it uses the base function that is defined as default. However, theabstractfunction is defined without any functionality(body) as default so it has to be overridden by the (non-abstract) subclasses. This override process is mandatory unlike thevirtualfunctions. - A
namespaceis a declarative region that provides a scope to the identifiers inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries. Code in header files should always use the fully qualified namespace name. finalspecifier is used to prevent overriding of a virtual function.- If a class that is defined with a
finalspecifier, can't be a base class. So, the classes withfinalspecifier, don't allow inheritance. - For the inherited classes;
- When an object of the derived class is created, the constructor of the base class executes first. Then, the constructor of the derived class executes. If there is a deeper inheritance hierarchy, then this flow executes in the same order (cascade).
- In the opposite way, when the derived class's object is destroyed, the destructors are called in the reverse order of the constructors. So, the destructor function of the derived class executes first, followed by execution of the destructor of the base class.
mutablespecifier is used to allow class members to be able to be modified even if the containing object is declared const.- One of the advantages of OOP is code reuse. There are two ways we can do code reuse either by the implementation of inheritance (
is-arelationship), or object composition (has-arelationship)- A
is-arelation is based on inheritance. For example, Car (derived) class hasis-arelation with the Vehicle (base) class. In short, the Car class is a sub-class of Vehicle class, so it can be described similarly asCar class is a (subclass of) Vehicle class. - A
has-arelation is based on composition. For example, Car class hashas-arelation with theWheelandBrakesclasses. In short, Wheel and Brakes are parts of a Car, so it can be described similarly asCar has wheel and brakes.
- A
typeidoperator returns the runtime type information of the parameter like a data type. For a class defined variable, it returns the information of the class (e.g.typeid(...).name()returns the class name).- The
typedefkeyword is used to create customized data types with aliased names. For example;istreamtype definition represents thebasic_istream<char>template customization.typedefkeyword is used liketypedef basic_istream<char> istream;ostreamtype definition represents thebasic_istream<char>template customization.typedefkeyword is used liketypedef basic_ostream<char> ostream;- A customized
pointerdefinition could be defined liketypedef Person * personPtr; - A customized
vectordefinition could be defined liketypedef std::vector<Person> vPerson; - A customized
vector pointerdefinition could be defined liketypedef std::vector<Person *> vPersonPtr; - A customized
functiondefinition could be defined liketypedef void (* personFunctionPtr)(std::char, int);
- The
string_viewtemplate specialization provides an efficient way to pass a read-only(constant), exception-safe, non-owning handle to the character data of any string. It is optimized for the constant string operations. For example, when declaring constant(enum) strings that shouldn't be modified anywhere, it is a good choice. constexprkeyword improves program performance by computing at compile time rather than run time. Unlikeconst,constexprcan also be applied to functions and class constructors.boolalphamanipulator formats and displays thebooleanvariables in text format (truefor1, andfalsefor0). Usingnoboolalphamanipulator disables this feature so it displays as1or0as in normal.showpointmanipulator is used to show(fill) the zeros of the decimal value. So, the variable could be displayed in a certain length. For example, a float variable with the2.300value shows as2.3in normal. By setting theshowpointmanipulator, it shows as2.30000. Setting theprecisionfunction declares how many characters will be displayed in total, so the zeros could be limited. After settingsetprecision(5), it shows as2.3000. On the other hand, using thenoshowpointmanipulator disables this feature, so the decimal point is only displayed for numbers whose decimal part is not zero as in normal.scientificmanipulator is used to display the numbers in scientific notations.cin.fail()method is used to check whether the entered input type is the same as the variable type. If it's not in the same data type, it returns 1. Otherwise, returns 0.- The
preprocessorsare programs that process the source code before compilation. Thepreprocessor directivesare special commands that are used to instruct the preprocessor. It begins with a#symbol and tells the preprocessor to the modify source code before compilation. Some predefined preprocessor macros:__FILE__preprocessor macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ‘#include’ or as the input file name argument.__LINE__preprocessor macro expands to the current input line number, in the form of a decimal integer constant. While we call it a predefined macro, it’s a pretty strange macro, since its “definition” changes with each new line of source code.__DATE__preprocessor macro expands to a string constant that describes the date on which the preprocessor is being run. The string constant contains eleven characters and looks like "Dec 14 2024". If the day of the month is less than 10, it is padded with a space on the left. If GCC cannot determine the current date, it will emit a warning message (once per compilation) and__DATE__will expand to"??? ?? ????".__TIME__preprocessor macro expands to a string constant that describes the time at which the preprocessor is being run. The string constant contains eight characters and looks like "00:30:10". If GCC cannot determine the current time, it will emit a warning message (once per compilation) and__TIME__will expand to"??:??:??".__STDC__preprocessor macro expands to the constant 1, to signify that this compiler conforms to ISO Standard C. If GNU CPP is used with a compiler other than GCC, this is not necessarily true. However, the preprocessor always conforms to the standard unless the-traditional-cppoption is used. This macro is not defined if the-traditional-cppoption is used.__cpluspluspreprocessor macro is defined when the C++ compiler is in use. It can be used to test whether a header is compiled by a C or a C++ compiler. This macro is similar to__STDC_VERSION__, in that it expands to a version number. Depending on the language standard selected, the value of the macro is199711Lfor the1998 C++ standard,201103Lfor the2011 C++ standard,201402Lfor the2014 C++ standard,201703Lfor the2017 C++ standard,202002Lfor the2020 C++ standard,202302Lfor the2023 C++ standard, or an unspecified value strictly larger than202302Lfor the experimental languages enabled by-std=c++26and-std=gnu++26.__OBJC__preprocessor macro is defined with value 1, when the Objective-C compiler is in use.__OBJC__can be used to test whether a header is compiled by aCor anObjective-Ccompiler.__ASSEMBLER__preprocessor macro is defined with value 1 when preprocessingassemblylanguage.
#definepreprocessor directive is used to define amacro(symbolic constant).Macrosare a way to represent a fragment of code or a symbolic constant value by giving it a name. When the preprocessor encounters themacroname in the code, it replaces it with the corresponding code fragment or value that is defined using the#definepreprocessor. The symbolic constants(macros) do not take up memory space, they don't store anywhere.std::ofstream(Output File Stream) is used to write into files.std::ifstream(Input File Stream) is used to read the data from a file.std::iosis a base class for all stream classes using narrow char characters. Both this class and its parent classios_base, define the components of streams that do not depend on whether the stream is an input or an output stream.std::ios::appwrites the new lines to the end of the file. So, the previous data in the file remains.std::ios::outopens file for writing and deletes the previous data in the file. It writes the new data instead.std::ios::inopens file for reading and allows inputs from the stream to get the data in the file.std::ios::binaryopens the file in binary mode.- Iterators are used to access and iterate through elements of data structures.
std::istream_iteratorprovides input iterator semantics for streams.std::ostream_iteratorprovides output iterator semantics for streams. std::splicecarries the elements of the list to the other one and purges the elements from the main list.std::mergecarries the elements of the list to the other one as sorted and purges the elements from the main list.std::uniqueremoves the duplicates.std::removeremoves the element in the list equal to value(parameter).std::priority_queuesorts the elements automatically and locates the biggest value to the top(front) of the queue. It is available to sort it descending and locate the lowers value to the top(front) by settings the 3.(_Compare) parameter. The default of it isless. The other options are:equal_to,not_equal_to,greater,greater_equal,less_equal.equal_rangefunction returns astd::paircontaining a pair of iterators as pair::first and pair::second.- The
pair::firstvalue is the same as theupper_boundfunction returns.upper_boundis a built-in function used to find the first element in a sorted range that is strictly greater than a given value. - The
pair::secondvalue is the same as thelower_boundfunction returns.lower_boundis a built-in function used to find the position of an element in a sorted range that has a value not less than the given value.
- The
std::bitsetrepresents a fixed-size sequence of N bits(each bit occupies 1 bit of memory).set()sets a given bit(1 or 0) to a particular value.flips()toggles every bit to its opposite value(1 to 0, 0 to 1).reset()sets every bit to false(0).size()returns the total number of bits.count()returns the number of bits which are set(1).any()checks whether any of the bits are on(1) and returns true if all the bits are set as 1. Otherwise, returns false.all()checks whether all of the bits are on(1) and returns true if all the bits are set as 1. Otherwise, returns false.none()checks whether any of the bits are on(1) and returns true if none of the bits are set as 1. Otherwise, returns false.test()checks the value of a bit and returns value at position. Returns 1 if the value is 1. Otherwise, returns 0.bit1 &= bit2performs binary logical AND operator and sets result into thebit1.bit1 |= bit2performs binary logical OR operator and sets result into thebit1.bit1 ^= bit2performs binary logical XOR operator and sets result into thebit1.~bit1performs binary logical NOT operator and flips the bits to opposite (1 to 0 or 0 to 1).>>=shifts the bits N step right.<<=shifts the bits N step left.to_string()converts bits to a string.to_ulong()returns a numerical interpretation (the integral equivalent of the bits) of the bitset by converting the bitset to an unsigned long.
- The header
<algorithm>defines a collection of functions especially designed to be used on ranges of elements. Some functions in<algorithm>:equalfunction compares whether the values are equal.mismatchfunction returns a pair of iterators. The pair's first iterator is the first array's unmatched first value. The pair's second iterator is the unmatched first value in the second array.removefunction removes all elements equal to the value(parameter).remove_copyfunction removes all elements equal to the value(parameter) and copies new sequence to the other one.remove_iffunction removes elements for whichpredicatefunction returns true.remove_copy_iffunction removes elements for whichpredicatefunction returns true and copies new sequence to the other one.replacefunction replaces each element of one value with another value.replace_copyfunction replaces each element of one value with another value and copies new sequence to the other one.replace_iffunction replaces each element for which a predicate returns true with another value.replace_copy_iffunction replaces each element for which a predicate returns true with another value and copies new sequence to the other one.
- Notes of some mathematical algorithm functions:
fill_nfunction is used to fill the N elements with a given default value.random_shufflerandomly shuffle the elements of a sequence.countcounts the number of copies of a value in a sequence.count_ifcounts the elements of a sequence for which a predicate is true.minmax_elementreturn a pair of iterators pointing to the minimum and maximum elements in a range.first==> min value,second==> max valuemin_elementreturns the minimum element in the range.minreturns the minimum value.max_elementreturns the maximum element in the range.maxreturns the maximum value.
accumulateaccumulates values in the range.for_eachapplies a function to every element of a sequence.transformfunction performs an operation to all elements in the array and, transforms the new elements to a new array.find_iffinds the first element in a sequence for which a predicate is true.find_if_notfinds the first element in a sequence for which a predicate is false.binary_searchsearches the value in the array and returns bool whether the value is in the array.all_ofchecks whether the predicate function returns true for all of the elements.any_ofchecks whether the predicate function returns true for any of the elements.none_ofchecks whether the predicate function returns false for all of the elements.swapswaps the elements with the each other.iter_swapuses iterator to swap the elements with the each other by the indexes.swap_rangesswaps each element in the range with the corresponding element in the range. The ranges must not overlap.unique_copyremoves the consecutive duplicate values and copies result to a sequence.uniqueremoves the consecutive duplicate values from the related array.copy_backwardcopies the elements to the other sequence. It has the same effect ascopy, but starts at the end of the range and works its way to the start, returning the start of the result.mergemerges two sorted ranges in one.reversereverses the sequence.includeschecks whether a sequence is a subsequence of the other one. It returns true if the sequence elements include the other sequence's elements.set_differencereturns the difference of two sorted ranges.set_intersectionreturns the intersected elements of two sorted ranges.set_symmetric_differencereturns the symmetric difference(The values which are in the array and not in merged array, or in merged array and not in main array) of two sorted ranges.set_unionreturns the union(The values which exist in one or both of the sequences) of two sorted ranges.equal_rangefinds the lower and upper bound values and returns them as a pair.lower_boundfinds the first value that is lower than or equal to the value.upper_boundfinds the first value that is upper than the value.
is_heapfunction determines whether the any elements in the range is a heap.is_heap_untilsearchs the end of a heap and returns an iterator pointing to the first element not in the heap.make_heapconstructs a heap in the range of the array.sort_heapsort the elements in the heap.
lambdaexpressions are a convenient way of defining an anonymous function object (a closure) right at the location where it's invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous functions.noexceptexpression specifies whether a function could throw exceptions. It is a suffix to a function declaration that represents a set of types that might be matched by an exception handler for any exception that exits a function.set_new_handlertakes a replacement handler as the argument, returns the previous handler. The newly configured handler function is the function called by allocation functions whenever a memory allocation attempt fails. It transfers control to your error-handling mechanism if the new operator fails to allocate memory. So, it allows us to catch and manage the memory allocation issues.overflow_errorspecifies the arithmetic overflow errors for the situations in which a result of an arithmetic computation is too large for the destination type.underflow_errorspecifies the arithmetic underflow errors for the situations in which the result of an arithmetic computation is less than the smallest value that can be stored in the computer.abortfunction aborts the execution and generate a core-dump.unique_ptris a smart pointer that automatically manages the dynamically allocated resources on the heap via a pointer.- A unique pointer can point to only one resource(a single object or dynamically allocated array of objects).
- A
unique_ptrcan transfer the ownership of the managed object to another unique_ptr if it's not declared as const. - A
unique_ptrvariable is created by using the new keyword, so it allocates dynamically. So, it must be freed by using thedeletekeyword. As the name suggests, the unique pointers free the dynamically allocated resource memory automatically when the destructor function is called, so it avoids the dynamically allocated resource memory issues.
- The last pointer of the linked data structure must point to a NULL pointer to mark the end of the list. Each node is connected with the next one and the last node doesn't have any node after itself so it can't point to other next node.
- Defining Dynamic Memory Allocation for the data structures that grow and shrink, saves memory.
size_tis aunsigneddata type that only represents non-negative values.- Some
stringfunctions:substrfunction constructs and returns a new string using the n characters starting at a position.comparefunction compares the value of the string objects and returns an integer.insertfunction inserts value of a string by starting at a position. If adding characters causes the length to exceed max_size(), length_error is thrown.replacefunction removes the characters in a range from the string. In place, the characters of the other string would be inserted.copyfunction copies substring into the string.c_strfunction returns a const pointer to null-terminated content. This is a handle to internal data so shouldn't be modified.datafunction returns anon-const pointerto contents. This is a pointer to the character sequence held by the string. Modifying the characters in the sequence is allowed.istringstreamis a class for input memory streams that stream the string into different variables.ostringstreamis a class for output memory streams. It effectively stores an instance of basic_string and performs output operations to it.stoifunction converts a string to an integer value.stolfunction converts a string to a long value.stoulfunction converts a string to an unsigned long value.stollfunction converts a string to a long long value.stoullfunction converts a string to an unsigned long long value.stoffunction converts a string to a float value.stodfunction converts a string to a double value.stoldfunction converts a string to a long double value.strtodfunction converts a string to a floating-point number. It returns the converted floating-point value and sets the string part to char pointer.strtolfunction converts a string to a long integer. It returns the converted long integer and sets the string part to a char pointer.strtoulfunction converts a string to a unsigned long integer. It returns the converted unsigned long integer and sets the string part to a char pointer.
C stringis stored as an array of characters.Cdoes not have a string type to create a string value. Instead, useschar[]type to create an array of characters to create a string value.strcpyfunction copies the C string pointed by the source into the array pointed by the destination, including the terminating null character.strncpyfunction copies N of the characters of the source to the array pointed by the destination.strchrfunction finds the occurrence of a character in a string.strpbrkfunction finds the first matched character of the search text in the text and returns the pointer to the first character of the search text found in the text. If there is no match, it returns NULL.memcpycopies N bytes from one memory location to the other memory location regardless of the type of data stored. It is meant to be the fastest library routine for memory-to-memory copy.memcmpcompares the first num bytes of the block of memory pointed by a pointer to the first num bytes pointed by other pointer. Returning 0 if they all match or a value different from zero representing which is greater if they do not.memmovecopies N bytes of the source string to the destination string, guaranteeing correct behavior for overlapping strings.const_castoperator is used to cast away the constness of variables. It configures a constant(const) variable as a non-const variable.- Notes of
CMakecommands:cmake_minimum_requiredsets the minimum required version of cmake for a project. Also updates the policy settings.projectsets the name of the project, and stores it in the variablePROJECT_NAME. When called from the top-levelCMakeLists.txtalso stores the project name in the variableCMAKE_PROJECT_NAME.setsets a normal, cache, or environment variable to a given value.- Setting normal value:
set(<variable> <value>... [PARENT_SCOPE]). It sets or unsets<variable>in the current function or directory scope. If at least one<value>...is given, it sets the variable to that value. Otherwise, it unsets the variable. This is equivalent tounset(<variable>). - Setting cache entry:
set(<variable> <value>... CACHE <type> <docstring> [FORCE]). It sets the given cache<variable>(cache entry). Since cache entries are meant to provide user-settable values this does not overwrite existing cache entries by default. Use the FORCE option to overwrite existing entries. - Setting environment variable:
set(ENV{<variable>} [<value>]). It sets an environment variable to the given value. Subsequent calls of$ENV{<variable>}will return this new value.
- Setting normal value:
add_executableadds an executable to the project using the specified source files.add_libraryadds a library to the project using the specified source files.- Setting normal libraries like
add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)add a library target called<name>to be built from the source files listed in the command invocation. The optional<type>specifies the type of library to be created:STATIC: An archive of object files for use when linking other targets.SHARED: A dynamic library that may be linked by other targets and loaded at runtime.MODULE: A plugin that may not be linked by other targets, but may be dynamically loaded at runtime using dlopen-like functionality.
- If no
<type>is given the default is STATIC or SHARED based on the value of the BUILD_SHARED_LIBS variable. The options are:EXCLUDE_FROM_ALLsets theEXCLUDE_FROM_ALLtarget property automatically.
- Setting normal libraries like
target_compile_featuresadds expected compiler features to a target liketarget_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])