parent
cc054bb24b
commit
36eed57ec2
44 changed files with 3525 additions and 44 deletions
@ -1 +1,130 @@ |
||||
# Introduction |
||||
# Introduction to C++ |
||||
|
||||
C++ is a general-purpose, high-performance programming language. It was developed by Bjarne Stroustrup at Bell Labs starting in 1979. C++ is an extension of the C programming language, adding features such as classes, objects, and exceptions. |
||||
|
||||
## Basics of C++ Programming |
||||
|
||||
Here are some basic components and concepts in C++ programming: |
||||
|
||||
### Including Libraries |
||||
|
||||
In C++, we use the `#include` directive to include libraries or header files into our program. For example, to include the standard input/output library, we write: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
``` |
||||
|
||||
### Main Function |
||||
|
||||
The entry point of a C++ program is the `main` function. Every C++ program must have a `main` function: |
||||
|
||||
```cpp |
||||
int main() { |
||||
// Your code goes here |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Input/Output |
||||
|
||||
To perform input and output operations in C++, we can use the built-in objects `std::cin` for input and `std::cout` for output, available in the `iostream` library. Here's an example of reading an integer and printing its value: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
int number; |
||||
std::cout << "Enter an integer: "; |
||||
std::cin >> number; |
||||
std::cout << "You entered: " << number << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Variables and Data Types |
||||
|
||||
C++ has several basic data types for representing integer, floating-point, and character values: |
||||
|
||||
- `int`: integer values |
||||
- `float`: single-precision floating-point values |
||||
- `double`: double-precision floating-point values |
||||
- `char`: single characters |
||||
|
||||
Variables must be declared with a data type before they can be used: |
||||
|
||||
```cpp |
||||
int x; |
||||
float y; |
||||
double z; |
||||
char c; |
||||
``` |
||||
|
||||
### Control Structures |
||||
|
||||
C++ provides control structures for conditional execution and iteration, such as `if`, `else`, `while`, `for`, and `switch` statements. |
||||
|
||||
#### If-Else Statement |
||||
```cpp |
||||
if (condition) { |
||||
// Code to execute if the condition is true |
||||
} else { |
||||
// Code to execute if the condition is false |
||||
} |
||||
``` |
||||
|
||||
#### While Loop |
||||
```cpp |
||||
while (condition) { |
||||
// Code to execute while the condition is true |
||||
} |
||||
``` |
||||
|
||||
#### For Loop |
||||
```cpp |
||||
for (initialization; condition; update) { |
||||
// Code to execute while the condition is true |
||||
} |
||||
``` |
||||
|
||||
#### Switch Statement |
||||
```cpp |
||||
switch (variable) { |
||||
case value1: |
||||
// Code to execute if variable == value1 |
||||
break; |
||||
case value2: |
||||
// Code to execute if variable == value2 |
||||
break; |
||||
// More cases... |
||||
default: |
||||
// Code to execute if variable does not match any case value |
||||
} |
||||
``` |
||||
|
||||
### Functions |
||||
|
||||
Functions are reusable blocks of code that can be called with arguments to perform a specific task. Functions are defined with a return type, a name, a parameter list, and a body. |
||||
|
||||
```cpp |
||||
ReturnType functionName(ParameterType1 parameter1, ParameterType2 parameter2) { |
||||
// Function body |
||||
// ... |
||||
return returnValue; |
||||
} |
||||
``` |
||||
|
||||
For example, here's a function that adds two integers and returns the result: |
||||
|
||||
```cpp |
||||
int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
|
||||
int main() { |
||||
int result = add(3, 4); |
||||
std::cout << "3 + 4 = " << result << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
This basic introduction to C++ should provide you with a good foundation for further learning. Explore more topics such as classes, objects, inheritance, polymorphism, templates, and the Standard Template Library (STL) to deepen your understanding of C++ and start writing more advanced programs. |
@ -1 +1,58 @@ |
||||
# First program |
||||
# First Program in C++ |
||||
|
||||
In this section, we'll discuss the basic structure of a C++ program, walk you through your first program (the "Hello, World!" example), and provide additional explanations of its syntax. |
||||
|
||||
## Hello, World! |
||||
|
||||
The first program that most people learn to write in any programming language is often a simple one that displays the message "Hello, World!" on the screen. Here's the classic "Hello, World!" program in C++: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::cout << "Hello, World!" << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
Let's break down the different components of this program: |
||||
|
||||
### Header Files & Preprocessor Directives |
||||
|
||||
The first line of the program `#include <iostream>` is a [preprocessor directive](https://en.cppreference.com/w/cpp/preprocessor) that tells the compiler to include the header file `iostream`. Header files provide function and class declarations that we can use in our C++ programs. |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
``` |
||||
|
||||
### `main()` Function |
||||
|
||||
In C++, the `main()` function serves as the entry point of your program. The operating system runs your program by calling this `main()` function. It should be defined only once in your program and must return an integer. |
||||
|
||||
```cpp |
||||
int main() { |
||||
// Your code goes here. |
||||
} |
||||
``` |
||||
|
||||
### Output to the Console |
||||
|
||||
To output text to the console, we use the `std::cout` object and the insertion operator `<<`. In the "Hello, World!" example, we used the following line to print "Hello, World!" to the console: |
||||
|
||||
```cpp |
||||
std::cout << "Hello, World!" << std::endl; |
||||
``` |
||||
|
||||
- `std::cout`: The standard "character output" stream that writes to the console |
||||
- `"Hello, World!"`: The string literal to print |
||||
- `std::endl`: The "end line" manipulator that inserts a newline character and flushes the output buffer |
||||
|
||||
### Return Statement |
||||
|
||||
Lastly, the `return 0;` statement informs the operating system that the program executed successfully. Returning any other integer value indicates that an error occurred: |
||||
|
||||
```cpp |
||||
return 0; |
||||
``` |
||||
|
||||
Now that you understand the basic components of a C++ program, you can write your first program, compile it, and run it to see the "Hello, World!" message displayed on the screen. |
@ -1 +1,57 @@ |
||||
# Setting up |
||||
# Setting Up C++ |
||||
|
||||
Setting up C++ requires a few steps, including installing a compiler, configuring an Integrated Development Environment (IDE), and creating a new C++ project. |
||||
|
||||
## 1. Installing a Compiler |
||||
|
||||
A compiler is required to convert C++ code into machine language. Some popular C++ compilers include: |
||||
|
||||
- GCC (GNU Compiler Collection) for Linux and macOS |
||||
- MinGW (Minimalist GNU for Windows) for Windows |
||||
- Microsoft Visual C++ for Windows |
||||
|
||||
To install a compiler, simply follow the instructions provided by the respective websites. |
||||
|
||||
## 2. Configuring an IDE |
||||
|
||||
An IDE is a software application that provides facilities for programming, such as code editing, debugging, and building. Some popular C++ IDEs include: |
||||
|
||||
- [Visual Studio](https://visualstudio.microsoft.com/vs/features/cplusplus/) (Windows, macOS) |
||||
- [Eclipse](https://eclipse.org) (Windows, macOS, Linux) |
||||
- [Code::Blocks](http://www.codeblocks.org) (Windows, macOS, Linux) |
||||
|
||||
After downloading and installing an IDE, you might need to configure it to use the installed compiler. Check the documentation of the respective IDE for instructions on how to do this. |
||||
|
||||
## 3. Creating a New C++ Project |
||||
|
||||
Once you have your IDE and compiler set up, you can create a new C++ project and start writing code. In general, follow these steps to create a new C++ project: |
||||
|
||||
1. Open the IDE and create a new project. |
||||
2. Select the project type (C++ Application or Console Application). |
||||
3. Specify the project name and location. |
||||
4. Let the IDE generate the main.cpp and build files (such as Makefile or CMakeLists.txt) for you. |
||||
|
||||
## Example: Hello World in C++ |
||||
|
||||
Create a new file called `main.cpp` within your project and include this code: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::cout << "Hello, World!" << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
Then, follow the IDE's instructions to build and run your program. You should see "Hello, World!" displayed in the console. |
||||
|
||||
## Summary |
||||
|
||||
Setting up C++ involves: |
||||
|
||||
1. Installing a compiler (e.g. GCC, MinGW, or MSVC) |
||||
2. Configuring an IDE (e.g. Visual Studio, Eclipse, or Code::Blocks) |
||||
3. Creating a new C++ project and writing code |
||||
|
||||
By following these steps, you'll be ready to start developing C++ applications! |
@ -1 +1,67 @@ |
||||
# Bitwise |
||||
# Bitwise Operations |
||||
|
||||
Bitwise operations are operations that directly manipulate the bits of a number. Bitwise operations are useful for various purposes, such as optimizing algorithms, performing certain calculations, and manipulating memory in lower-level programming languages like C and C++. |
||||
|
||||
Here is a quick summary of common bitwise operations in C++: |
||||
|
||||
### 1. Bitwise AND (`&`) |
||||
|
||||
The bitwise AND operation (`&`) is a binary operation that takes two numbers, compares them bit by bit, and returns a new number where each bit is set (1) if the corresponding bits in both input numbers are set (1); otherwise, the bit is unset (0). |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = 5 & 3; // result will be 1 (0000 0101 & 0000 0011 = 0000 0001) |
||||
``` |
||||
|
||||
### 2. Bitwise OR (`|`) |
||||
|
||||
The bitwise OR operation (`|`) is a binary operation that takes two numbers, compares them bit by bit, and returns a new number where each bit is set (1) if at least one of the corresponding bits in either input number is set (1); otherwise, the bit is unset (0). |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = 5 | 3; // result will be 7 (0000 0101 | 0000 0011 = 0000 0111) |
||||
``` |
||||
|
||||
### 3. Bitwise XOR (`^`) |
||||
|
||||
The bitwise XOR (exclusive OR) operation (`^`) is a binary operation that takes two numbers, compares them bit by bit, and returns a new number where each bit is set (1) if the corresponding bits in the input numbers are different; otherwise, the bit is unset (0). |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = 5 ^ 3; // result will be 6 (0000 0101 ^ 0000 0011 = 0000 0110) |
||||
``` |
||||
|
||||
### 4. Bitwise NOT (`~`) |
||||
|
||||
The bitwise NOT operation (`~`) is a unary operation that takes a single number, and returns a new number where each bit is inverted (1 becomes 0, and 0 becomes 1). |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = ~5; // result will be -6 (1111 1010) |
||||
``` |
||||
|
||||
### 5. Bitwise Left Shift (`<<`) |
||||
|
||||
The bitwise left shift operation (`<<`) is a binary operation that takes two numbers, a value and a shift amount, and returns a new number by shifting the bits of the value to the left by the specified shift amount. The vacated bits are filled with zeros. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = 5 << 1; // result will be 10 (0000 0101 << 1 = 0000 1010) |
||||
``` |
||||
|
||||
### 6. Bitwise Right Shift (`>>`) |
||||
|
||||
The bitwise right shift operation (`>>`) is a binary operation that takes two numbers, a value and a shift amount, and returns a new number by shifting the bits of the value to the right by the specified shift amount. The vacated bits are filled with zeros or sign bit depending on the input value being signed or unsigned. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
int result = 5 >> 1; // result will be 2 (0000 0101 >> 1 = 0000 0010) |
||||
``` |
||||
|
||||
These were the most common bitwise operations in C++. Remember to use them carefully and understand their behavior when applied to specific data types and scenarios. |
@ -1 +1,104 @@ |
||||
# Operators |
||||
# Operators in C++ |
||||
|
||||
Operators in C++ are symbols that perform various operations on data, such as arithmetic, comparison, and logical operations. They are used to manipulate and evaluate expressions and variables. |
||||
|
||||
Here is a list of the commonly used operator types in C++: |
||||
|
||||
1. **Arithmetic Operators**: These are used for performing arithmetic operations like addition, subtraction, multiplication, and division. |
||||
|
||||
- `+`: addition |
||||
```cpp |
||||
int sum = 5 + 3; // sum will be 8 |
||||
``` |
||||
- `-`: subtraction |
||||
```cpp |
||||
int difference = 5 - 3; // difference will be 2 |
||||
``` |
||||
- `*`: multiplication |
||||
```cpp |
||||
int product = 5 * 3; // product will be 15 |
||||
``` |
||||
- `/`: division |
||||
```cpp |
||||
int quotient = 15 / 3; // quotient will be 5 |
||||
``` |
||||
- `%`: modulo (remainder) |
||||
```cpp |
||||
int remainder = 7 % 3; // remainder will be 1 |
||||
``` |
||||
|
||||
2. **Comparison (Relational) Operators**: These are used to compare two values and return true or false based on the comparison. |
||||
|
||||
- `==`: equal to |
||||
```cpp |
||||
bool isEqual = (5 == 3); // isEqual will be false |
||||
``` |
||||
- `!=`: not equal to |
||||
```cpp |
||||
bool isNotEqual = (5 != 3); // isNotEqual will be true |
||||
``` |
||||
- `<`: less than |
||||
```cpp |
||||
bool isLess = (5 < 3); // isLess will be false |
||||
``` |
||||
- `>`: greater than |
||||
```cpp |
||||
bool isGreater = (5 > 3); // isGreater will be true |
||||
``` |
||||
- `<=`: less than or equal to |
||||
```cpp |
||||
bool isLessOrEqual = (5 <= 3); // isLessOrEqual will be false |
||||
``` |
||||
- `>=`: greater than or equal to |
||||
```cpp |
||||
bool isGreaterOrEqual = (5 >= 3); // isGreaterOrEqual will be true |
||||
``` |
||||
|
||||
3. **Logical Operators**: These operators are used to perform logical operations such as AND (&&), OR (||), and NOT (!) on boolean values. |
||||
|
||||
- `&&`: logical AND |
||||
```cpp |
||||
bool result = (true && false); // result will be false |
||||
``` |
||||
- `||`: logical OR |
||||
```cpp |
||||
bool result = (true || false); // result will be true |
||||
``` |
||||
- `!`: logical NOT |
||||
```cpp |
||||
bool result = !false; // result will be true |
||||
``` |
||||
|
||||
4. **Assignment Operators**: These are used to assign values to variables. |
||||
|
||||
- `=`: simple assignment |
||||
```cpp |
||||
int x = 5; // x gets the value 5 |
||||
``` |
||||
- `+=`: addition assignment |
||||
```cpp |
||||
int x = 5; |
||||
x += 3; // x gets the value 8 (5 + 3) |
||||
``` |
||||
- `-=`: subtraction assignment |
||||
```cpp |
||||
int x = 5; |
||||
x -= 3; // x gets the value 2 (5 - 3) |
||||
``` |
||||
- `*=`: multiplication assignment |
||||
```cpp |
||||
int x = 5; |
||||
x *= 3; // x gets the value 15 (5 * 3) |
||||
``` |
||||
- `/=`: division assignment |
||||
```cpp |
||||
int x = 15; |
||||
x /= 3; // x gets the value 5 (15 / 3) |
||||
``` |
||||
- `%=`: modulo assignment |
||||
```cpp |
||||
int x = 7; |
||||
x %= 3; // x gets the value 1 (7 % 3) |
||||
``` |
||||
|
||||
These are some of the main operator categories in C++. Each operator allows you to perform specific operations, making your code more efficient and concise. |
@ -1 +1,74 @@ |
||||
# Functions |
||||
# Functions in C++ |
||||
|
||||
A **function** is a group of statements that perform a specific task, organized as a separate unit in a program. Functions help in breaking the code into smaller, manageable, and reusable blocks. |
||||
|
||||
There are mainly two types of functions in C++: |
||||
|
||||
1. **Standard library functions**: Pre-defined functions available in the C++ standard library, such as `printf()`, `scanf()`, `sqrt()`, and many more. These functions are part of the standard library, so you need to include the appropriate header file to use them. |
||||
|
||||
2. **User-defined functions**: Functions created by the programmer to perform a specific task. To create a user-defined function, you need to define the function and call it in your code. |
||||
|
||||
## Defining a Function |
||||
|
||||
The general format for defining a function in C++ is: |
||||
|
||||
```cpp |
||||
return_type function_name(parameter list) { |
||||
// function body |
||||
} |
||||
``` |
||||
|
||||
- `return_type`: Data type of the output produced by the function. It can be `void`, indicating that the function doesn't return any value. |
||||
- `function_name`: Name given to the function, following C++ naming conventions. |
||||
- `parameter list`: List of input parameters/arguments that are needed to perform the task. It is optional, and when no parameters are needed, you can leave it blank or use the keyword `void`. |
||||
|
||||
## Example |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
using namespace std; |
||||
|
||||
// Function to add two numbers |
||||
int addNumbers(int a, int b) { |
||||
int sum = a + b; |
||||
return sum; |
||||
} |
||||
|
||||
int main() { |
||||
int num1 = 5, num2 = 10; |
||||
int result = addNumbers(num1, num2); // Calling the function |
||||
cout << "The sum is: " << result << endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
In this example, the function `addNumbers` takes two integer parameters, `a` and `b`, and returns the sum of the numbers. We then call this function from the `main()` function and display the result. |
||||
|
||||
## Function Prototypes |
||||
|
||||
In some cases, you might want to use a function before actually defining it. To do this, you need to declare a **function prototype** at the beginning of your code. |
||||
|
||||
A function prototype is a declaration of the function without its body, and it informs the compiler about the function's name, return type, and parameters. |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
using namespace std; |
||||
|
||||
// Function prototype |
||||
int multiplyNumbers(int x, int y); |
||||
|
||||
int main() { |
||||
int num1 = 3, num2 = 7; |
||||
int result = multiplyNumbers(num1, num2); // Calling the function |
||||
cout << "The product is: " << result << endl; |
||||
return 0; |
||||
} |
||||
|
||||
// Function definition |
||||
int multiplyNumbers(int x, int y) { |
||||
int product = x * y; |
||||
return product; |
||||
} |
||||
``` |
||||
|
||||
In this example, we use a function prototype for `multiplyNumbers()` before defining it. This way, we can call the function from the `main()` function even though it hasn't been defined yet in the code. |
@ -1 +1,134 @@ |
||||
# Data types |
||||
# Data Types in C++ |
||||
|
||||
In C++, data types are used to categorize different types of data that a program can process. They are essential for determining the type of value a variable can hold and how much memory space it will occupy. Some basic data types in C++ include integers, floating-point numbers, characters, and booleans. |
||||
|
||||
## Fundamental Data Types |
||||
|
||||
### Integer (int) |
||||
Integers are whole numbers that can store both positive and negative values. The size of `int` depends on the system architecture (usually 4 bytes). |
||||
|
||||
Example: |
||||
```cpp |
||||
int num = 42; |
||||
``` |
||||
|
||||
There are variants of `int` that can hold different ranges of numbers: |
||||
- short (`short int`): Smaller range than `int`. |
||||
- long (`long int`): Larger range than `int`. |
||||
- long long (`long long int`): Even larger range than `long int`. |
||||
|
||||
### Floating-Point (float, double) |
||||
Floating-point types represent real numbers, i.e., numbers with a decimal point. There are two main floating-point types: |
||||
|
||||
1. **float**: Provides single-precision floating-point numbers. It typically occupies 4 bytes of memory. |
||||
|
||||
Example: |
||||
```cpp |
||||
float pi = 3.14f; |
||||
``` |
||||
|
||||
2. **double**: Provides double-precision floating-point numbers. It consumes more memory (usually 8 bytes) but has a higher precision than `float`. |
||||
|
||||
Example: |
||||
```cpp |
||||
double pi_high_precision = 3.1415926535; |
||||
``` |
||||
|
||||
### Character (char) |
||||
Characters represent a single character, such as a letter, digit, or symbol. They are stored using the ASCII value of the symbol and typically occupy 1 byte of memory. |
||||
|
||||
Example: |
||||
```cpp |
||||
char letter = 'A'; |
||||
``` |
||||
|
||||
### Boolean (bool) |
||||
Booleans represent logical values: `true` or `false`. They usually occupy 1 byte of memory. |
||||
|
||||
Example: |
||||
```cpp |
||||
bool is_cpp_great = true; |
||||
``` |
||||
|
||||
## Derived Data Types |
||||
|
||||
Derived data types are types that are derived from fundamental data types. Some examples include: |
||||
|
||||
### Arrays |
||||
Arrays are used to store multiple values of the same data type in consecutive memory locations. |
||||
|
||||
Example: |
||||
```cpp |
||||
int numbers[5] = {1, 2, 3, 4, 5}; |
||||
``` |
||||
|
||||
### Pointers |
||||
Pointers are used to store the memory address of a variable. |
||||
|
||||
Example: |
||||
```cpp |
||||
int num = 42; |
||||
int* pNum = # |
||||
``` |
||||
|
||||
### References |
||||
References are an alternative way to share memory locations between variables, allowing you to create an alias for another variable. |
||||
|
||||
Example: |
||||
```cpp |
||||
int num = 42; |
||||
int& numRef = num; |
||||
``` |
||||
|
||||
## User-Defined Data Types |
||||
|
||||
User-defined data types are types that are defined by the programmer, such as structures, classes, and unions. |
||||
|
||||
### Structures (struct) |
||||
Structures are used to group variables of different data types together under a single name. |
||||
|
||||
Example: |
||||
```cpp |
||||
struct Person { |
||||
string name; |
||||
int age; |
||||
float height; |
||||
}; |
||||
|
||||
Person p1 = {"John Doe", 30, 5.9}; |
||||
``` |
||||
|
||||
### Classes (class) |
||||
Classes are similar to structures, but they can also have member functions and access specifiers. |
||||
|
||||
Example: |
||||
```cpp |
||||
class Person { |
||||
public: |
||||
string name; |
||||
int age; |
||||
|
||||
void printInfo() { |
||||
cout << "Name: " << name << ", Age: " << age << endl; |
||||
}; |
||||
}; |
||||
|
||||
Person p1; |
||||
p1.name = "John Doe"; |
||||
p1.age = 30; |
||||
``` |
||||
|
||||
### Unions (union) |
||||
Unions are used to store different data types in the same memory location. |
||||
|
||||
Example: |
||||
```cpp |
||||
union Data { |
||||
int num; |
||||
char letter; |
||||
float decimal; |
||||
}; |
||||
|
||||
Data myData; |
||||
myData.num = 42; |
||||
``` |
@ -1 +1,52 @@ |
||||
# Memory model |
||||
# Memory Model in C++ |
||||
|
||||
The memory model in C++ defines how the program stores and accesses data in computer memory. It consists of different segments, such as the Stack, Heap, Data and Code segments. Each of these segments is used to store different types of data and has specific characteristics. |
||||
|
||||
## Stack Memory |
||||
|
||||
Stack memory is used for automatic storage duration variables, such as local variables and function call data. Stack memory is managed by the compiler, and it's allocation and deallocation are done automatically. The stack memory is also a LIFO (Last In First Out) data structure, meaning that the most recent data allocated is the first to be deallocated. |
||||
|
||||
```cpp |
||||
void functionExample() { |
||||
int x = 10; // x is stored in the stack memory |
||||
} |
||||
``` |
||||
|
||||
## Heap Memory |
||||
|
||||
Heap memory is used for dynamic storage duration variables, such as objects created using the `new` keyword. The programmer has control over the allocation and deallocation of heap memory using `new` and `delete` operators. Heap memory is a larger pool of memory than the stack, but has a slower access time. |
||||
|
||||
```cpp |
||||
void functionExample() { |
||||
int* p = new int; // dynamically allocated int in heap memory |
||||
*p = 10; |
||||
// more code |
||||
delete p; // deallocate memory |
||||
} |
||||
``` |
||||
|
||||
## Data Segment |
||||
|
||||
The Data segment is composed of two parts: the initialized data segment and the uninitialized data segment. The initialized data segment stores global, static, and constant variables with initial values, whereas the uninitialized segment stores uninitialized global and static variables. |
||||
|
||||
```cpp |
||||
// Initialized data segment |
||||
int globalVar = 10; // global variables |
||||
static int staticVar = 10; // static local variables |
||||
const int constVar = 10; // constant variables with value |
||||
|
||||
// Uninitialized data segment |
||||
int globalVar; // uninitialized global variables |
||||
``` |
||||
|
||||
## Code Segment |
||||
|
||||
The Code segment (also known as the Text segment) stores the executable code (machine code) of the program. It's usually located in a read-only area of memory to prevent accidental modification. |
||||
|
||||
```cpp |
||||
void functionExample() { |
||||
// The machine code for this function is stored in the code segment. |
||||
} |
||||
``` |
||||
|
||||
In summary, understanding the memory model in C++ helps to optimize the usage of memory resources and improves overall program performance. |
@ -1 +1,103 @@ |
||||
# Namespaces |
||||
# Namespaces in C++ |
||||
|
||||
In C++, a namespace is a named scope or container that is used to organize and enclose a collection of code elements, such as variables, functions, classes, and other namespaces. They are mainly used to divide and manage the code base, giving developers control over name collisions and the specialization of code. |
||||
|
||||
### Syntax |
||||
|
||||
Here's the syntax for declaring a namespace: |
||||
|
||||
```cpp |
||||
namespace identifier { |
||||
// code elements |
||||
} |
||||
``` |
||||
|
||||
### Using Namespaces |
||||
|
||||
To access elements within a namespace, you can use the scope resolution operator `::`. Here are some examples: |
||||
|
||||
#### Declaring and accessing a namespace |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
namespace animals { |
||||
std::string dog = "Bobby"; |
||||
std::string cat = "Lilly"; |
||||
} |
||||
|
||||
int main() { |
||||
std::cout << "Dog's name: " << animals::dog << std::endl; |
||||
std::cout << "Cat's name: " << animals::cat << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
#### Nesting namespaces |
||||
|
||||
Namespaces can be nested within other namespaces: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
namespace outer { |
||||
int x = 10; |
||||
|
||||
namespace inner { |
||||
int y = 20; |
||||
} |
||||
} |
||||
|
||||
int main() { |
||||
std::cout << "Outer x: " << outer::x << std::endl; |
||||
std::cout << "Inner y: " << outer::inner::y << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### `using` Keyword |
||||
|
||||
You can use the `using` keyword to import namespaced elements into the current scope. However, this might lead to name conflicts if multiple namespaces have elements with the same name. |
||||
|
||||
#### Using a single element from a namespace |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
namespace animals { |
||||
std::string dog = "Bobby"; |
||||
std::string cat = "Lilly"; |
||||
} |
||||
|
||||
int main() { |
||||
using animals::dog; |
||||
|
||||
std::cout << "Dog's name: " << dog << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
#### Using the entire namespace |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
namespace animals { |
||||
std::string dog = "Bobby"; |
||||
std::string cat = "Lilly"; |
||||
} |
||||
|
||||
int main() { |
||||
using namespace animals; |
||||
|
||||
std::cout << "Dog's name: " << dog << std::endl; |
||||
std::cout << "Cat's name: " << cat << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
In conclusion, namespaces are a useful mechanism in C++ to organize code, avoid naming conflicts, and manage the visibility of code elements. |
@ -1 +1,55 @@ |
||||
# Code splitting |
||||
# Code Splitting |
||||
|
||||
Code splitting refers to the process of breaking down a large code base into smaller, more manageable files or modules. This helps improve the organization, maintainability, and readability of the code. In C++, code splitting is generally achieved through the use of separate compilation, header files, and source files. |
||||
|
||||
#### Header Files (.h or .hpp) |
||||
|
||||
Header files, usually with the `.h` or `.hpp` extension, are responsible for declaring classes, functions, and variables that are needed by multiple source files. They act as an interface between different parts of the code, making it easier to manage dependencies and reduce the chances of duplicated code. |
||||
|
||||
Example of a header file: |
||||
|
||||
```cpp |
||||
// example.h |
||||
#ifndef EXAMPLE_H |
||||
#define EXAMPLE_H |
||||
|
||||
class Example { |
||||
public: |
||||
void printMessage(); |
||||
}; |
||||
|
||||
#endif |
||||
``` |
||||
|
||||
#### Source Files (.cpp) |
||||
|
||||
Source files, with the `.cpp` extension, are responsible for implementing the actual functionality defined in the corresponding header files. They include the header files as needed and provide the function and class method definitions. |
||||
|
||||
Example of a source file: |
||||
|
||||
```cpp |
||||
// example.cpp |
||||
#include "example.h" |
||||
#include <iostream> |
||||
|
||||
void Example::printMessage() { |
||||
std::cout << "Hello, code splitting!" << std::endl; |
||||
} |
||||
``` |
||||
|
||||
#### Separate Compilation |
||||
|
||||
C++ allows for separate compilation, which means that each source file can be compiled independently into an object file. These object files can then be linked together to form the final executable. This provides faster build times when making changes to a single source file since only that file needs to be recompiled, and the other object files can be reused. |
||||
|
||||
Example of separate compilation and linking: |
||||
|
||||
```sh |
||||
# Compile each source file into an object file |
||||
g++ -c main.cpp -o main.o |
||||
g++ -c example.cpp -o example.o |
||||
|
||||
# Link object files together to create the executable |
||||
g++ main.o example.o -o my_program |
||||
``` |
||||
|
||||
By following the code splitting technique, you can better organize your C++ codebase, making it more manageable and maintainable. |
@ -1 +1,66 @@ |
||||
# Structuring codebase |
||||
# Structuring Codebase |
||||
|
||||
Structuring codebase is an essential part of software development that deals with organizing and modularizing your code to make it more maintainable, efficient, and easier to understand. A well-structured codebase enhances collaboration, simplifies adding new features, and makes debugging faster. In C++, there are various techniques to help you structure your codebase effectively. |
||||
|
||||
## Namespaces |
||||
|
||||
Namespaces are one of the tools in C++ to organize your code by providing a named scope for different identifiers you create, like functions, classes, and variables. They help avoid name clashes and make your code more modular. |
||||
|
||||
```cpp |
||||
namespace MyNamespace { |
||||
int aFunction() { |
||||
// function implementation |
||||
} |
||||
} |
||||
// to use the function |
||||
MyNamespace::aFunction(); |
||||
``` |
||||
|
||||
## Include Guards |
||||
|
||||
Include guards are a tool for preventing multiple inclusions of a header file in your project. They consist of preprocessor directives that conditionally include the header file only once, even if it's included in multiple places. |
||||
|
||||
```cpp |
||||
#ifndef MY_HEADER_FILE_H |
||||
#define MY_HEADER_FILE_H |
||||
|
||||
// Your code here |
||||
|
||||
#endif // MY_HEADER_FILE_H |
||||
``` |
||||
|
||||
## Header and Source Files |
||||
|
||||
Separating your implementation and declarations into header (*.h) and source (*.cpp) files is a key aspect of structuring your codebase in C++. Header files usually contain class and function declarations, while source files contain their definitions. |
||||
|
||||
// MyClass.h |
||||
```cpp |
||||
#ifndef MY_CLASS_H |
||||
#define MY_CLASS_H |
||||
|
||||
class MyClass |
||||
{ |
||||
public: |
||||
MyClass(); |
||||
int myMethod(); |
||||
}; |
||||
|
||||
#endif // MY_CLASS_H |
||||
``` |
||||
|
||||
// MyClass.cpp |
||||
```cpp |
||||
#include "MyClass.h" |
||||
|
||||
MyClass::MyClass() { |
||||
// constructor implementation |
||||
} |
||||
|
||||
int MyClass::myMethod() { |
||||
// method implementation |
||||
} |
||||
``` |
||||
|
||||
## Code Formatting |
||||
|
||||
Consistent code formatting and indentation play a crucial role in structuring your codebase, making it easier to read and understand for both you and other developers. A style guide such as the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) can help you maintain consistent formatting throughout your project. |
@ -1 +1,109 @@ |
||||
# Rule of zero five three |
||||
# Rule of Zero, Five, Three |
||||
|
||||
**Rule of Zero, Three, and Five in C++** |
||||
|
||||
The Rule of Zero, Three, and Five is a set of guidelines for managing object resources in modern C++, related to structures and classes. These rules deal with the default behavior of constructors, destructors, and other special member functions that are necessary for proper resource management. |
||||
|
||||
**Rule of Zero** |
||||
|
||||
The Rule of Zero states that if a class or structure does not explicitly manage resources, it should not define any of the special member functions, i.e., destructor, copy constructor, copy assignment operator, move constructor, and move assignment operator. The compiler will automatically generate these functions, and the behavior will be correct for managing resources like memory and file handles. |
||||
|
||||
*Example:* |
||||
|
||||
```cpp |
||||
struct MyResource { |
||||
std::string name; |
||||
int value; |
||||
}; |
||||
``` |
||||
|
||||
In this example, MyResource is a simple structure that does not manage any resources, so it does not define any special member functions. The compiler will generate them automatically, and the behavior will be correct. |
||||
|
||||
**Rule of Three** |
||||
|
||||
The Rule of Three states that a class or structure that manages resources should define the following three special member functions: |
||||
|
||||
1. Destructor |
||||
2. Copy constructor |
||||
3. Copy assignment operator |
||||
|
||||
These functions are necessary for proper resource management, such as releasing memory or correctly handling deep copies. |
||||
|
||||
*Example:* |
||||
|
||||
```cpp |
||||
class MyResource { |
||||
public: |
||||
// Constructor and destructor |
||||
MyResource() : data(new int[100]) {} |
||||
~MyResource() { delete[] data; } |
||||
|
||||
// Copy constructor |
||||
MyResource(const MyResource& other) : data(new int[100]) { |
||||
std::copy(other.data, other.data + 100, data); |
||||
} |
||||
|
||||
// Copy assignment operator |
||||
MyResource& operator=(const MyResource& other) { |
||||
if (&other == this) { return *this; } |
||||
std::copy(other.data, other.data + 100, data); |
||||
return *this; |
||||
} |
||||
|
||||
private: |
||||
int* data; |
||||
}; |
||||
``` |
||||
|
||||
In this example, MyResource is a class that manages a resource (an array of integers), so it defines the destructor, copy constructor, and copy assignment operator. |
||||
|
||||
**Rule of Five** |
||||
|
||||
The Rule of Five extends the Rule of Three to include two additional special member functions: |
||||
|
||||
1. Move constructor |
||||
2. Move assignment operator |
||||
|
||||
Modern C++ introduces move semantics, which allows for more efficient handling of resources by transferring ownership without necessarily copying all the data. |
||||
|
||||
*Example:* |
||||
|
||||
```cpp |
||||
class MyResource { |
||||
public: |
||||
// Constructors and destructor |
||||
MyResource() : data(new int[100]) {} |
||||
~MyResource() { delete[] data; } |
||||
|
||||
// Copy constructor |
||||
MyResource(const MyResource& other) : data(new int[100]) { |
||||
std::copy(other.data, other.data + 100, data); |
||||
} |
||||
|
||||
// Copy assignment operator |
||||
MyResource& operator=(const MyResource& other) { |
||||
if (&other == this) { return *this; } |
||||
std::copy(other.data, other.data + 100, data); |
||||
return *this; |
||||
} |
||||
|
||||
// Move constructor |
||||
MyResource(MyResource&& other) noexcept : data(other.data) { |
||||
other.data = nullptr; |
||||
} |
||||
|
||||
// Move assignment operator |
||||
MyResource& operator=(MyResource&& other) noexcept { |
||||
if (&other == this) { return *this; } |
||||
delete[] data; |
||||
data = other.data; |
||||
other.data = nullptr; |
||||
return *this; |
||||
} |
||||
|
||||
private: |
||||
int* data; |
||||
}; |
||||
``` |
||||
|
||||
In this example, MyResource is a class that manages a resource (an array of integers), so it defines all five special member functions for proper resource management and move semantics. |
@ -1 +1,120 @@ |
||||
# Oop |
||||
# Object-Oriented Programming (OOP) in C++ |
||||
|
||||
Object-oriented programming (OOP) is a programming paradigm that uses objects, which are instances of classes, to perform operations and interact with each other. In C++, you can achieve OOP through the use of classes and objects. |
||||
|
||||
### Classes |
||||
|
||||
A class is a blueprint for creating objects. It defines the structure (data members) and behavior (member functions) for a type of object. Here's an example of a simple class: |
||||
|
||||
```cpp |
||||
class Dog { |
||||
public: |
||||
std::string name; |
||||
int age; |
||||
|
||||
void bark() { |
||||
std::cout << name << " barks!" << std::endl; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
This `Dog` class has two data members: `name` and `age`, and one member function `bark`. You can create an object of this class and access its members like this: |
||||
|
||||
```cpp |
||||
Dog myDog; |
||||
myDog.name = "Fido"; |
||||
myDog.age = 3; |
||||
myDog.bark(); // Output: Fido barks! |
||||
``` |
||||
|
||||
### Encapsulation |
||||
|
||||
Encapsulation is the concept of bundling data and functions that operate on that data within a single unit, such as a class. It helps to hide the internal implementation details of a class and expose only the necessary information and functionalities. In C++, you can use access specifiers like `public`, `private`, and `protected` to control the visibility and accessibility of class members. For example: |
||||
|
||||
```cpp |
||||
class Dog { |
||||
private: |
||||
std::string name; |
||||
int age; |
||||
|
||||
public: |
||||
void setName(std::string n) { |
||||
name = n; |
||||
} |
||||
|
||||
void setAge(int a) { |
||||
age = a; |
||||
} |
||||
|
||||
void bark() { |
||||
std::cout << name << " barks!" << std::endl; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
In this example, we've made the `name` and `age` data members `private` and added public member functions `setName` and `setAge` to modify them. This way, the internal data of the `Dog` class is protected and only accessible through the provided functions. |
||||
|
||||
### Inheritance |
||||
|
||||
Inheritance is the concept of deriving new classes from existing ones, which enables code reusability and organization. In C++, inheritance is achieved by using a colon `:` followed by the base class' access specifier and the base class name. For example: |
||||
|
||||
```cpp |
||||
class Animal { |
||||
public: |
||||
void breathe() { |
||||
std::cout << "I can breathe" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
class Dog : public Animal { |
||||
public: |
||||
void bark() { |
||||
std::cout << "Dog barks!" << std::endl; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
In this example, the `Dog` class inherits from the `Animal` class, so the `Dog` class can access the `breathe` function from the `Animal` class. When you create a `Dog` object, you can use both `breathe` and `bark` functions. |
||||
|
||||
```cpp |
||||
Dog myDog; |
||||
myDog.breathe(); // Output: I can breathe |
||||
myDog.bark(); // Output: Dog barks! |
||||
``` |
||||
|
||||
### Polymorphism |
||||
|
||||
Polymorphism allows you to use a single interface to represent different types. In C++, it's mainly achieved using function overloading, virtual functions, and overriding. For example: |
||||
|
||||
```cpp |
||||
class Animal { |
||||
public: |
||||
virtual void makeSound() { |
||||
std::cout << "The Animal makes a sound" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
class Dog : public Animal { |
||||
public: |
||||
void makeSound() override { |
||||
std::cout << "Dog barks!" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
class Cat : public Animal { |
||||
public: |
||||
void makeSound() override { |
||||
std::cout << "Cat meows!" << std::endl; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
In this example, we have an `Animal` base class with a virtual `makeSound` function. We then derive two classes, `Dog` and `Cat`, which override the `makeSound` function. This enables polymorphic behavior, where an `Animal` pointer or reference can be used to access the correct `makeSound` function depending on the derived class type. |
||||
|
||||
```cpp |
||||
Animal *animals[2] = {new Dog, new Cat}; |
||||
animals[0]->makeSound(); // Output: Dog barks! |
||||
animals[1]->makeSound(); // Output: Cat meows! |
||||
``` |
||||
|
||||
That's a brief overview of object-oriented programming concepts in C++. |
@ -1 +1,76 @@ |
||||
# Multiple inheritance |
||||
# Multiple Inheritance |
||||
|
||||
Multiple inheritance is a feature in C++ where a class can inherit characteristics (data members and member functions) from more than one parent class. The concept is similar to single inheritance (where a class inherits from a single base class), but in multiple inheritance, a class can have multiple base classes. |
||||
|
||||
When a class inherits multiple base classes, it becomes a mixture of their properties and behaviors, and can override or extend them as needed. |
||||
|
||||
### Syntax |
||||
|
||||
Here is the syntax to declare a class with multiple inheritance: |
||||
|
||||
```cpp |
||||
class DerivedClass : access-specifier BaseClass1, access-specifier BaseClass2, ... |
||||
{ |
||||
// class body |
||||
}; |
||||
``` |
||||
|
||||
The `DerivedClass` will inherit members from both `BaseClass1` and `BaseClass2`. The `access-specifier` (like `public`, `protected`, or `private`) determines the accessibility of the inherited members. |
||||
|
||||
### Example |
||||
|
||||
Here is an example of multiple inheritance in action: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
// Base class 1 |
||||
class Animal |
||||
{ |
||||
public: |
||||
void eat() |
||||
{ |
||||
std::cout << "I can eat!" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
// Base class 2 |
||||
class Mammal |
||||
{ |
||||
public: |
||||
void breath() |
||||
{ |
||||
std::cout << "I can breathe!" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
// Derived class inheriting from both Animal and Mammal |
||||
class Dog : public Animal, public Mammal |
||||
{ |
||||
public: |
||||
void bark() |
||||
{ |
||||
std::cout << "I can bark! Woof woof!" << std::endl; |
||||
} |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
Dog myDog; |
||||
|
||||
// Calling members from both base classes |
||||
myDog.eat(); |
||||
myDog.breath(); |
||||
|
||||
// Calling a member from the derived class |
||||
myDog.bark(); |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Note |
||||
|
||||
In some cases, multiple inheritance can lead to complications such as ambiguity and the "diamond problem". Ensure that you use multiple inheritance judiciously and maintain well-structured and modular classes to prevent issues. |
||||
|
||||
For more information on C++ multiple inheritance and related topics, refer to C++ documentation or a comprehensive C++ programming guide. |
@ -1 +1,43 @@ |
||||
# Access violations |
||||
# Access Violations |
||||
|
||||
An access violation is a specific type of error that occurs when a program attempts to access an illegal memory location. In C++, access violations are most commonly caused by: |
||||
|
||||
1. **Dereferencing a null or invalid pointer.** |
||||
2. **Accessing an array out of bounds.** |
||||
3. **Reading or writing to memory freed by the user or the operating system.** |
||||
|
||||
It is crucial to identify access violations because they can lead to unpredictable behavior, application crashes, or corruption of data. |
||||
|
||||
#### Examples |
||||
|
||||
##### 1. Dereferencing null or invalid pointer |
||||
|
||||
```cpp |
||||
int *p = nullptr; |
||||
int x = *p; // Access violation: trying to access null pointer's content |
||||
``` |
||||
|
||||
##### 2. Accessing an array out of bounds |
||||
|
||||
```cpp |
||||
int arr[5] = {1, 2, 3, 4, 5}; |
||||
int y = arr[5]; // Access violation: index out of bounds (valid indices are 0-4) |
||||
``` |
||||
|
||||
##### 3. Reading or writing to freed memory |
||||
|
||||
```cpp |
||||
int* p2 = new int[10]; |
||||
delete[] p2; |
||||
p2[3] = 42; // Access violation: writing to memory that has been freed |
||||
``` |
||||
|
||||
#### Debugging Access Violations |
||||
|
||||
Tools like _debuggers_, _static analyzers_, and _profilers_ can help identify access violations in your code. For example: |
||||
|
||||
* **Microsoft Visual Studio**: Use the built-in debugger to identify the line of code responsible for the access violation error. |
||||
|
||||
* **Valgrind**: A popular Linux tool that detects memory leaks and access violations in your C++ programs. |
||||
|
||||
* **AddressSanitizer**: A runtime memory error detector for C++ that can detect out-of-bounds accesses, memory leaks, and use-after-free errors. |
@ -1 +1,83 @@ |
||||
# Exception handling |
||||
# Overview |
||||
|
||||
Exception handling in C++ is a mechanism to handle errors, anomalies, or unexpected events that can occur during the runtime execution of a program. This allows the program to continue running or exit gracefully when encountering errors instead of crashing abruptly. |
||||
|
||||
C++ provides a set of keywords and constructs for implementing exception handling: |
||||
|
||||
- `try`: Defines a block of code that should be monitored for exceptions. |
||||
- `catch`: Specifies the type of exception to be caught and the block of code that shall be executed when that exception occurs. |
||||
- `throw`: Throws an exception that will be caught and handled by the appropriate catch block. |
||||
- `noexcept`: Specifies a function that doesn't throw exceptions or terminates the program if an exception is thrown within its scope. |
||||
|
||||
## Example |
||||
|
||||
Here's an example demonstrating the basic usage of exception handling: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
int divide(int a, int b) { |
||||
if (b == 0) { |
||||
throw "Division by zero!"; |
||||
} |
||||
return a / b; |
||||
} |
||||
|
||||
int main() { |
||||
int num1, num2; |
||||
|
||||
std::cout << "Enter two numbers for division: "; |
||||
std::cin >> num1 >> num2; |
||||
|
||||
try { |
||||
int result = divide(num1, num2); |
||||
std::cout << "The result is: " << result << std::endl; |
||||
} catch (const char* msg) { |
||||
std::cerr << "Error: " << msg << std::endl; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
In this example, we define a function `divide` that throws an exception if `b` is zero. In the `main` function, we use a `try` block to call `divide` and output the result. If an exception is thrown, it is caught inside the `catch` block, which outputs an error message. This way, we can handle the error gracefully rather than letting the program crash when attempting to divide by zero. |
||||
|
||||
## Standard Exceptions |
||||
|
||||
C++ provides a standard set of exception classes under the `<stdexcept>` library which can be used as the exception type for more specific error handling. Some of these classes include: |
||||
|
||||
- `std::exception`: Base class for all standard exceptions. |
||||
- `std::logic_error`: Represents errors which can be detected statically by the program. |
||||
- `std::runtime_error`: Represents errors occurring during the execution of a program. |
||||
|
||||
Here's an example showing how to use standard exceptions: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <stdexcept> |
||||
|
||||
int divide(int a, int b) { |
||||
if (b == 0) { |
||||
throw std::runtime_error("Division by zero!"); |
||||
} |
||||
return a / b; |
||||
} |
||||
|
||||
int main() { |
||||
int num1, num2; |
||||
|
||||
std::cout << "Enter two numbers for division: "; |
||||
std::cin >> num1 >> num2; |
||||
|
||||
try { |
||||
int result = divide(num1, num2); |
||||
std::cout << "The result is: " << result << std::endl; |
||||
} catch (const std::exception& e) { |
||||
std::cerr << "Error: " << e.what() << std::endl; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
In this example, we modified the `divide` function to throw a `std::runtime_error` instead of a simple string. The catch block now catches exceptions derived from `std::exception` and uses the member function `what()` to display the error message. |
@ -1 +1,131 @@ |
||||
# Language concepts |
||||
# Language Concepts in C++ |
||||
|
||||
C++ is a powerful, high-level, object-oriented programming language that offers several key language concepts. These concepts provide the foundation upon which you can build efficient, reliable, and maintainable programs. Here's a brief summary of some important language concepts in C++. |
||||
|
||||
### 1. Variables and Data Types |
||||
C++ provides various fundamental data types such as `int`, `float`, `double`, `char`, and `bool` to declare and manipulate variables in a program. |
||||
|
||||
Example: |
||||
```cpp |
||||
int age = 25; |
||||
float height = 1.7f; |
||||
double salary = 50000.0; |
||||
char grade = 'A'; |
||||
bool isEmployed = true; |
||||
``` |
||||
|
||||
### 2. Control Structures |
||||
Control structures enable you to control the flow of execution of a program. Key control structures in C++ include: |
||||
|
||||
- Conditional statement: `if`, `else`, and `else if` |
||||
- Loop constructs: `for`, `while`, and `do-while` |
||||
- Switch-case construct |
||||
|
||||
Example: |
||||
```cpp |
||||
// If-else statement |
||||
if (age > 18) { |
||||
cout << "You are eligible to vote."; |
||||
} else { |
||||
cout << "You are not eligible to vote."; |
||||
} |
||||
|
||||
// For loop |
||||
for (int i = 0; i < 5; i++) { |
||||
cout << "Hello World!"; |
||||
} |
||||
``` |
||||
|
||||
### 3. Functions |
||||
Functions in C++ allow you to break down a large program into small, manageable, and reusable pieces of code. |
||||
|
||||
Example: |
||||
```cpp |
||||
int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
|
||||
int main() { |
||||
int sum = add(10, 20); |
||||
cout << "The sum is: " << sum; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### 4. Arrays and Vectors |
||||
Arrays and Vectors are commonly used data structures to store and manipulate a collection of elements of the same datatype. |
||||
|
||||
Example: |
||||
```cpp |
||||
// Array |
||||
int marks[] = {90, 80, 95, 85}; |
||||
|
||||
// Vector |
||||
vector<int> scores = {10, 20, 30, 40}; |
||||
``` |
||||
|
||||
### 5. Pointers |
||||
Pointers are variables that store memory addresses of other variables. They enable more efficient handling of memory, and are useful for working with dynamic data structures. |
||||
|
||||
Example: |
||||
```cpp |
||||
int num = 10; |
||||
int* p = # // p stores the address of num |
||||
``` |
||||
|
||||
### 6. Structures and Classes |
||||
Structures and Classes are user-defined data types that allow grouping of variables and functions under a single name. |
||||
|
||||
Example: |
||||
```cpp |
||||
// Structure |
||||
struct Student { |
||||
string name; |
||||
int age; |
||||
}; |
||||
|
||||
// Class |
||||
class Employee { |
||||
public: |
||||
string name; |
||||
int age; |
||||
void displayInfo() { |
||||
cout << "Name: " << name << "\nAge: " << age; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
### 7. Inheritance and Polymorphism |
||||
Inheritance is a mechanism that allows a class to inherit properties and methods from a base class. Polymorphism enables you to use a base class type to represent derived class objects. |
||||
|
||||
Example: |
||||
```cpp |
||||
class Base { |
||||
public: |
||||
void display() { |
||||
cout << "This is the base class."; |
||||
} |
||||
}; |
||||
|
||||
class Derived : public Base { |
||||
public: |
||||
void display() { |
||||
cout << "This is the derived class."; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
### 8. Exception Handling |
||||
C++ provides a mechanism to handle exceptions(runtime errors) gracefully using `try`, `catch`, and `throw` constructs. |
||||
|
||||
Example: |
||||
```cpp |
||||
try { |
||||
// Code that might throw an exception |
||||
int result = a / b; |
||||
} catch (const exception &e) { |
||||
cout << "Caught an exception: " << e.what(); |
||||
} |
||||
``` |
||||
|
||||
These are some of the key language concepts in C++, which will help you to understand the language better and develop efficient and maintainable applications. |
@ -1 +1,81 @@ |
||||
# Iterators |
||||
# Iterators |
||||
|
||||
Iterators are objects in the C++ Standard Library (`STL`) that help us traverse containers like arrays, lists, and vectors. Essentially, they act as a bridge between container classes and algorithms. Iterators behave similar to pointers but provide a more generalized and abstract way of accessing elements in a container. |
||||
|
||||
There are different types of iterators which you would encounter depending on their use cases: |
||||
|
||||
1. **Input Iterator**: Used to read elements in a container only once, in a forward direction. They cannot modify elements. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::vector<int> nums = {1, 2, 3, 4}; |
||||
std::istream_iterator<int> input(std::cin); |
||||
std::copy(input, std::istream_iterator<int>(), std::back_inserter(nums)); |
||||
``` |
||||
|
||||
2. **Output Iterator**: Used to write elements in a container only once, in a forward direction. They cannot re-write elements. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::vector<int> nums = {1, 2, 3, 4}; |
||||
std::ostream_iterator<int> output(std::cout, ", "); |
||||
std::copy(nums.begin(), nums.end(), output); |
||||
``` |
||||
|
||||
3. **Forward Iterator**: Similar to input iterators but can be used for multiple passes over the elements in a container. They cannot move backward. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::forward_list<int> nums = {1, 2, 3, 4}; |
||||
std::forward_list<int>::iterator itr = nums.begin(); |
||||
while (itr != nums.end()) { |
||||
std::cout << *itr << " "; |
||||
++itr; |
||||
} |
||||
``` |
||||
|
||||
4. **Bidirectional Iterator**: These iterators offer the ability to move both forward and backward in a container. List and set containers have bi-directional iterators. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::list<int> nums = {1, 2, 3, 4}; |
||||
std::list<int>::iterator itr; |
||||
for (itr = nums.begin(); itr != nums.end(); ++itr) { |
||||
std::cout << *itr << " "; |
||||
} |
||||
for (--itr; itr != nums.begin(); --itr) { |
||||
std::cout << *itr << " "; |
||||
} |
||||
``` |
||||
|
||||
5. **Random Access Iterator**: These iterators provide the most flexible ways to access elements in a container. They can move forwards, backwards, jump directly to other elements, and access elements at a given index. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::vector<int> nums = {1, 2, 3, 4}; |
||||
std::vector<int>::iterator itr; |
||||
for (itr = nums.begin(); itr != nums.end(); ++itr) { |
||||
std::cout << *itr << " "; |
||||
} |
||||
for (itr -= 1; itr != nums.begin() - 1; --itr) { |
||||
std::cout << *itr << " "; |
||||
} |
||||
``` |
||||
|
||||
For most cases, you would want to start with the `auto` keyword and the appropriate container methods (like `begin()` and `end()`) to work with iterators. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
std::vector<int> nums = {1, 2, 3, 4}; |
||||
for (auto itr = nums.begin(); itr != nums.end(); ++itr) { |
||||
std::cout << *itr << " "; |
||||
} |
||||
``` |
||||
|
||||
When working with algorithms, remember that the C++ Standard Library provides various algorithms that already utilize iterators for tasks like searching, sorting, and manipulating elements. |
@ -1 +1,89 @@ |
||||
# Algorithms |
||||
# STL Algorithms |
||||
|
||||
The Standard Template Library (STL) in C++ provides a collection of generic algorithms that are designed to work with various container classes. These algorithms are implemented as functions and can be applied to different data structures, such as arrays, vectors, lists, and others. The primary header file for algorithms is `<algorithm>`. |
||||
|
||||
## Key Concepts |
||||
|
||||
### Sorting |
||||
|
||||
Sorting refers to arranging a sequence of elements in a specific order. The STL provides several sorting algorithms, such as `std::sort`, `std::stable_sort`, and `std::partial_sort`. |
||||
|
||||
#### std::sort |
||||
|
||||
`std::sort` is used to sort a range of elements [first, last) in non-descending order (by default). You can also use custom comparison functions or lambda expressions to change the sorting order. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
#include <algorithm> |
||||
#include <vector> |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::vector<int> nums = {10, 9, 8, 7, 6, 5}; |
||||
std::sort(nums.begin(), nums.end()); |
||||
|
||||
for (int num : nums) { |
||||
std::cout << num << ' '; |
||||
} |
||||
// Output: 5 6 7 8 9 10 |
||||
} |
||||
``` |
||||
|
||||
### Searching |
||||
|
||||
Searching refers to finding if a particular element is present within a given range of elements. STL provides various searching algorithms, such as `std::find`, `std::binary_search`, and `std::find_if`. |
||||
|
||||
#### std::find |
||||
|
||||
`std::find` is used to find the iterator of the first occurrence of a given value within the range [first, last). |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
#include <algorithm> |
||||
#include <vector> |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::vector<int> nums = {5, 6, 7, 8, 9, 10}; |
||||
auto it = std::find(nums.begin(), nums.end(), 9); |
||||
|
||||
if (it != nums.end()) { |
||||
std::cout << "Found 9 at position: " << (it - nums.begin()); |
||||
} else { |
||||
std::cout << "9 not found"; |
||||
} |
||||
// Output: Found 9 at position: 4 |
||||
} |
||||
``` |
||||
|
||||
### Modifying Sequences |
||||
|
||||
The STL also provides algorithms for modifying sequences, such as `std::remove`, `std::replace`, and `std::unique`. |
||||
|
||||
#### std::remove |
||||
|
||||
`std::remove` is used to remove all instances of a value from a container within the given range [first, last). Note that the function does not resize the container after removing elements. |
||||
|
||||
Example: |
||||
|
||||
```cpp |
||||
#include <algorithm> |
||||
#include <vector> |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::vector<int> nums = {5, 6, 7, 6, 8, 6, 9, 6, 10}; |
||||
nums.erase(std::remove(nums.begin(), nums.end(), 6), nums.end()); |
||||
|
||||
for (int num : nums) { |
||||
std::cout << num << ' '; |
||||
} |
||||
// Output: 5 7 8 9 10 |
||||
} |
||||
``` |
||||
|
||||
## Summary |
||||
|
||||
STL algorithms in C++ provide a set of useful functions for key operations such as sorting, searching, and modifying sequences. The algorithms can be used with a variety of container classes, making them highly versatile and an essential part of C++ programming. |
||||
|
@ -1 +1,90 @@ |
||||
# Date time |
||||
# C++ Date Time |
||||
|
||||
In C++, you can work with dates and times using the `chrono` library, which is part of the Standard Library (STL). The `chrono` library provides various data types and functions to represent and manipulate time durations, time points, and clocks. |
||||
|
||||
### Duration |
||||
|
||||
A `duration` represents a span of time, which can be expressed in various units such as seconds, minutes, hours, etc. To create a duration, use the `std::chrono::duration` template class. Common predefined duration types are: |
||||
|
||||
- `std::chrono::seconds` |
||||
- `std::chrono::minutes` |
||||
- `std::chrono::hours` |
||||
|
||||
**Example:** |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <chrono> |
||||
|
||||
int main() { |
||||
std::chrono::seconds sec(5); |
||||
std::chrono::minutes min(2); |
||||
std(chrono)::hours hr(1); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Time Point |
||||
|
||||
A `time_point` represents a specific point in time. It is usually created using a combination of duration and a clock. In C++, there are three clock types provided by the `chrono` library: |
||||
|
||||
- `std::chrono::system_clock`: Represents the system-wide real time wall clock. |
||||
- `std::chrono::steady_clock`: Represents a monotonic clock that is guaranteed to never be adjusted. |
||||
- `std::chrono::high_resolution_clock`: Represents the clock with the shortest tick period. |
||||
|
||||
**Example:** |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <chrono> |
||||
|
||||
int main() { |
||||
std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Clock |
||||
|
||||
A clock provides access to the current time. It consists of the following elements: |
||||
|
||||
- `time_point`: A specific point in time. |
||||
- `duration`: The time duration between two time points. |
||||
- `now()`: A static function that returns the current time point. |
||||
|
||||
**Example:** |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <chrono> |
||||
|
||||
int main() { |
||||
// Get the current time_point using system_clock |
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); |
||||
|
||||
// Get the time_point 1 hour from now |
||||
std::chrono::system_clock::time_point one_hour_from_now = now + std::chrono::hours(1); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Converting Time Points to Calendar Time |
||||
|
||||
To convert a time point to calendar representation, you can use the `std::chrono::system_clock::to_time_t` function. |
||||
|
||||
**Example:** |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <chrono> |
||||
#include <ctime> |
||||
|
||||
int main() { |
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); |
||||
std::time_t now_c = std::chrono::system_clock::to_time_t(now); |
||||
std::cout << "Current time: " << std::ctime(&now_c) << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
This summarizes the basic functionality of working with date and time in C++ using the `chrono` library. You can find more advanced features, such as casting durations and time arithmetic, in the [C++ reference](https://en.cppreference.com/w/cpp/chrono). |
@ -1 +1,97 @@ |
||||
# Ccontainers |
||||
# C++ Containers |
||||
|
||||
C++ Containers are a part of the Standard Template Library (STL) that provide data structures to store and organize data. There are several types of containers, each with its own characteristics and use cases. Here, we discuss some of the commonly used containers: |
||||
|
||||
## 1. Vector |
||||
|
||||
Vectors are dynamic arrays that can resize themselves as needed. They store elements in a contiguous memory location, allowing fast random access using indices. |
||||
|
||||
### Example |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <vector> |
||||
|
||||
int main() { |
||||
std::vector<int> vec = {1, 2, 3, 4, 5}; |
||||
|
||||
vec.push_back(6); // Add an element to the end |
||||
|
||||
std::cout << "Vector contains:"; |
||||
for (int x : vec) { |
||||
std::cout << ' ' << x; |
||||
} |
||||
std::cout << std::endl; |
||||
} |
||||
``` |
||||
|
||||
## 2. List |
||||
|
||||
A list is a doubly-linked list that allows elements to be inserted or removed from any position in constant time. It does not support random access. Lists are better than vectors for scenarios where you need to insert or remove elements in the middle frequently. |
||||
|
||||
### Example |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <list> |
||||
|
||||
int main() { |
||||
std::list<int> lst = {1, 2, 3, 4, 5}; |
||||
|
||||
lst.push_back(6); // Add an element to the end |
||||
|
||||
std::cout << "List contains:"; |
||||
for (int x : lst) { |
||||
std::cout << ' ' << x; |
||||
} |
||||
std::cout << std::endl; |
||||
} |
||||
``` |
||||
|
||||
## 3. Map |
||||
|
||||
A map is an associative container that stores key-value pairs. It supports the retrieval of values based on their keys. The keys are sorted in ascending order by default. |
||||
|
||||
### Example |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <map> |
||||
|
||||
int main() { |
||||
std::map<std::string, int> m; |
||||
|
||||
m["one"] = 1; |
||||
m["two"] = 2; |
||||
|
||||
std::cout << "Map contains:" << std::endl; |
||||
for (const auto &pair : m) { |
||||
std::cout << pair.first << ": " << pair.second << std::endl; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
## 4. Unordered_map |
||||
|
||||
Similar to a map, an unordered map stores key-value pairs, but it is implemented using a hash table. This means unordered_map has faster average-case performance compared to map, since it does not maintain sorted order. However, worst-case performance can be worse than map. |
||||
|
||||
### Example |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <unordered_map> |
||||
|
||||
int main() { |
||||
std::unordered_map<std::string, int> um; |
||||
|
||||
um["one"] = 1; |
||||
um["two"] = 2; |
||||
|
||||
std::cout << "Unordered map contains:" << std::endl; |
||||
for (const auto &pair : um) { |
||||
std::cout << pair.first << ": " << pair.second << std::endl; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
These are just a few examples of C++ containers. There are other container types, such as `set`, `multiset`, `deque`, `stack`, `queue`, and `priority_queue`. Each container has its own use cases and unique characteristics. Learning about these containers and when to use them can greatly improve your efficiency and effectiveness in using C++. |
@ -1 +1,85 @@ |
||||
# Stl |
||||
# C++ Standard Template Library (STL) |
||||
|
||||
The C++ Standard Template Library (STL) is a collection of header files that provide several data structures, algorithms, and functions to simplify your C++ coding experience. The primary purpose of the STL is to save time and increase efficiency by providing a ready-to-use set of useful tools. The most commonly used features of the STL can be divided into three main categories: containers, algorithms, and iterators. |
||||
|
||||
## Containers |
||||
|
||||
Containers are the data structures used for data storage and manipulation in C++. They are classified into four types: sequence containers, associative containers, unordered associative containers, and container adaptors. |
||||
|
||||
1. **Sequence Containers**: These are linear data structures that store elements in a sequential manner. Examples include: |
||||
- `std::vector`: A dynamic array that grows and shrinks at runtime. |
||||
```cpp |
||||
std::vector<int> my_vector; |
||||
``` |
||||
- `std::list`: A doubly linked list. |
||||
```cpp |
||||
std::list<int> my_list; |
||||
``` |
||||
- `std::deque`: A double-ended queue allowing insertion and deletion at both ends. |
||||
```cpp |
||||
std::deque<int> my_deque; |
||||
``` |
||||
|
||||
2. **Associative Containers**: These containers store data in a sorted manner with unique keys. Examples include: |
||||
- `std::set`: A collection of unique elements sorted by keys. |
||||
```cpp |
||||
std::set<int> my_set; |
||||
``` |
||||
- `std::map`: A collection of key-value pairs sorted by keys. |
||||
```cpp |
||||
std::map<std::string, int> my_map; |
||||
``` |
||||
|
||||
3. **Unordered Associative Containers**: These containers store data in an unordered manner using hash tables. Examples include: |
||||
- `std::unordered_set`: A collection of unique elements in no specific order. |
||||
```cpp |
||||
std::unordered_set<int> my_unordered_set; |
||||
``` |
||||
- `std::unordered_map`: A collection of key-value pairs in no specific order. |
||||
```cpp |
||||
std::unordered_map<std::string, int> my_unordered_map; |
||||
``` |
||||
|
||||
4. **Container Adaptors**: These are containers based on other existing containers. Examples include: |
||||
- `std::stack`: A LIFO data structure based on deque or list. |
||||
```cpp |
||||
std::stack<int> my_stack; |
||||
``` |
||||
- `std::queue`: A FIFO data structure based on deque or list. |
||||
```cpp |
||||
std::queue<int> my_queue; |
||||
``` |
||||
- `std::priority_queue`: A sorted queue based on vector or deque. |
||||
```cpp |
||||
std::priority_queue<int> my_priority_queue; |
||||
``` |
||||
|
||||
## Algorithms |
||||
|
||||
The STL provides several generic algorithms that can be used to perform various operations on the data stored in containers. They are divided into five categories: non-modifying sequence algorithms, modifying sequence algorithms, sorting algorithms, sorted range algorithms, and numeric algorithms. |
||||
|
||||
Some examples include `std::find`, `std::replace`, `std::sort`, and `std::binary_search`. |
||||
|
||||
For example, to sort a vector, you can use the following code: |
||||
|
||||
```cpp |
||||
std::vector<int> my_vec = {4, 2, 5, 1, 3}; |
||||
std::sort(my_vec.begin(), my_vec.end()); |
||||
``` |
||||
|
||||
## Iterators |
||||
|
||||
Iterators are a fundamental concept in the STL, as they provide a unified way to access elements in containers. Iterators can be thought of as an advanced form of pointers. |
||||
|
||||
Each container has its own iterator type, which can be used to traverse elements and modify values. The most common iterator operations are `begin()` and `end()` for getting iterators pointing to the first and one past the last element of a container, respectively. |
||||
|
||||
For example, to iterate through a vector and print its elements, you can use the following code: |
||||
|
||||
```cpp |
||||
std::vector<int> my_vec = {1, 2, 3, 4, 5}; |
||||
for(auto it = my_vec.begin(); it != my_vec.end(); ++it) { |
||||
std::cout << *it << " "; |
||||
} |
||||
``` |
||||
|
||||
This is just a brief overview of the C++ Standard Template Library. There are many other features and functions available in the STL, and familiarizing yourself with them is crucial for efficient C++ programming. |
@ -1 +1,84 @@ |
||||
# Template specialization |
||||
# Template Specialization |
||||
|
||||
Template specialization is a way to customize or modify the behavior of a template for a specific type or a set of types. This can be useful when you want to optimize the behavior or provide specific implementation for a certain type, without affecting the overall behavior of the template for other types. |
||||
|
||||
There are two main ways you can specialize a template: |
||||
|
||||
1. **Full specialization:** This occurs when you provide a specific implementation for a specific type or set of types. |
||||
|
||||
2. **Partial specialization:** This occurs when you provide a more general implementation for a subset of types that match a certain pattern or condition. |
||||
|
||||
### Full Template Specialization |
||||
|
||||
Full specialization is used when you want to create a separate implementation of a template for a specific type. To do this, you need to use keyword `template<>` followed by the function template with the desired specialized type. |
||||
|
||||
Here is an example: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
template <typename T> |
||||
void printData(const T& data) { |
||||
std::cout << "General template: " << data << std::endl; |
||||
} |
||||
|
||||
template <> |
||||
void printData(const char*& data) { |
||||
std::cout << "Specialized template for const char*: " << data << std::endl; |
||||
} |
||||
|
||||
int main() { |
||||
int a = 5; |
||||
const char* str = "Hello, world!"; |
||||
printData(a); // General template: 5 |
||||
printData(str); // Specialized template for const char*: Hello, world! |
||||
} |
||||
``` |
||||
|
||||
### Partial Template Specialization |
||||
|
||||
Partial specialization is used when you want to create a separate implementation of a template for a subset of types that match a certain pattern or condition. |
||||
|
||||
Here is an example of how you can partially specialize a template class: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
template <typename K, typename V> |
||||
class MyPair { |
||||
public: |
||||
MyPair(K k, V v) : key(k), value(v) {} |
||||
|
||||
void print() const { |
||||
std::cout << "General template: key = " << key << ", value = " << value << std::endl; |
||||
} |
||||
|
||||
private: |
||||
K key; |
||||
V value; |
||||
}; |
||||
|
||||
template <typename T> |
||||
class MyPair<T, int> { |
||||
public: |
||||
MyPair(T k, int v) : key(k), value(v) {} |
||||
|
||||
void print() const { |
||||
std::cout << "Partial specialization for int values: key = " << key |
||||
<< ", value = " << value << std::endl; |
||||
} |
||||
|
||||
private: |
||||
T key; |
||||
int value; |
||||
}; |
||||
|
||||
int main() { |
||||
MyPair<double, std::string> p1(3.2, "example"); |
||||
MyPair<char, int> p2('A', 65); |
||||
p1.print(); // General template: key = 3.2, value = example |
||||
p2.print(); // Partial specialization for int values: key = A, value = 65 |
||||
} |
||||
``` |
||||
|
||||
In this example, the `MyPair` template class is partially specialized to provide a different behavior when the second template parameter is of type `int`. |
@ -1 +1,104 @@ |
||||
# Idioms |
||||
# C++ Idioms |
||||
|
||||
C++ idioms are well-established patterns or techniques that are commonly used in C++ programming to achieve a specific outcome. They help make code efficient, maintainable, and less error-prone. Here are some of the common C++ idioms: |
||||
|
||||
## 1. Resource Acquisition is Initialization (RAII) |
||||
|
||||
This idiom ensures that resources are always properly acquired and released by tying their lifetime to the lifetime of an object. When the object gets created, it acquires the resources and when it gets destroyed, it releases them. |
||||
|
||||
```cpp |
||||
class Resource { |
||||
public: |
||||
Resource() { /* Acquire resource */ } |
||||
~Resource() { /* Release resource */ } |
||||
}; |
||||
|
||||
void function() { |
||||
Resource r; // Resource is acquired |
||||
// ... |
||||
} // Resource is released when r goes out of scope |
||||
``` |
||||
|
||||
## 2. Rule of Three |
||||
|
||||
If a class defines any one of the following, it should define all three: copy constructor, copy assignment operator, and destructor. |
||||
|
||||
```cpp |
||||
class MyClass { |
||||
public: |
||||
MyClass(); |
||||
MyClass(const MyClass& other); // Copy constructor |
||||
MyClass& operator=(const MyClass& other); // Copy assignment operator |
||||
~MyClass(); // Destructor |
||||
}; |
||||
``` |
||||
|
||||
## 3. Rule of Five |
||||
|
||||
With C++11, the rule of three was extended to five, covering move constructor and move assignment operator. |
||||
|
||||
```cpp |
||||
class MyClass { |
||||
public: |
||||
MyClass(); |
||||
MyClass(const MyClass& other); // Copy constructor |
||||
MyClass(MyClass&& other); // Move constructor |
||||
MyClass& operator=(const MyClass& other); // Copy assignment operator |
||||
MyClass& operator=(MyClass&& other); // Move assignment operator |
||||
~MyClass(); // Destructor |
||||
}; |
||||
``` |
||||
|
||||
## 4. PImpl (Pointer to Implementation) Idiom |
||||
|
||||
This idiom is used to separate the implementation details of a class from its interface, resulting in faster compile times and the ability to change implementation without affecting clients. |
||||
|
||||
```cpp |
||||
// header file |
||||
class MyClass { |
||||
public: |
||||
MyClass(); |
||||
~MyClass(); |
||||
void someMethod(); |
||||
|
||||
private: |
||||
class Impl; |
||||
Impl* pImpl; |
||||
}; |
||||
|
||||
// implementation file |
||||
class MyClass::Impl { |
||||
public: |
||||
void someMethod() { /* Implementation */ } |
||||
}; |
||||
|
||||
MyClass::MyClass() : pImpl(new Impl()) {} |
||||
MyClass::~MyClass() { delete pImpl; } |
||||
void MyClass::someMethod() { pImpl->someMethod(); } |
||||
``` |
||||
|
||||
## 5. Non-Virtual Interface (NVI) |
||||
|
||||
This enforces a fixed public interface and allows subclasses to only override specific private or protected virtual methods. |
||||
|
||||
```cpp |
||||
class Base { |
||||
public: |
||||
void publicMethod() { |
||||
// Common behavior |
||||
privateMethod(); // Calls overridden implementation |
||||
} |
||||
|
||||
protected: |
||||
virtual void privateMethod() = 0; // Pure virtual method |
||||
}; |
||||
|
||||
class Derived : public Base { |
||||
protected: |
||||
virtual void privateMethod() override { |
||||
// Derived implementation |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
These are just a few examples of the many idioms in C++ programming. They can provide guidance when designing and implementing your code, but it's essential to understand the underlying concepts to adapt them to different situations. |
@ -1 +1,64 @@ |
||||
# Cpp11 14 |
||||
# C++11 and C++14 ### |
||||
|
||||
**C++11** |
||||
The C++11 standard, also known as C++0x, was officially released in September 2011. It introduced several new language features and improvements, including: |
||||
|
||||
- **Auto**: Allows compiler to infer the variable type based on its initializing expression. |
||||
```cpp |
||||
auto integer = 42; // integer is of int type |
||||
auto floating = 3.14; // floating is of double type |
||||
``` |
||||
|
||||
- **Range-Based for Loop**: Provides foreach-like semantics for iterating through a container or array. |
||||
```cpp |
||||
std::vector<int> numbers {1, 2, 3, 4}; |
||||
for (int number : numbers) { |
||||
std::cout << number << std::endl; |
||||
} |
||||
``` |
||||
|
||||
- **Lambda Functions**: Anonymous functions that allow the creation of function objects more easily. |
||||
```cpp |
||||
auto add = [](int a, int b) -> int { return a + b; }; |
||||
int sum = add(42, 13); // sum is equal to 55 |
||||
``` |
||||
|
||||
- **nullptr**: A new keyword to represent null pointers, more type-safe than using a literal '0' or "NULL". |
||||
```cpp |
||||
int *ptr = nullptr; |
||||
``` |
||||
|
||||
- **Thread Support Library**: Provides a standard way to work with threads and synchronize data access across threads. |
||||
```cpp |
||||
std::thread t([]() { std::cout << "Hello from another thread\n"; }); |
||||
t.join(); |
||||
``` |
||||
|
||||
**C++14** |
||||
The C++14 standard was officially released in December 2014 as a small extension over C++11, focusing more on fine-tuning language features and fixing issues. Some of the new features introduced: |
||||
|
||||
- **Generic Lambdas**: Allows lambda function parameters to be declared with 'auto' type placeholders. |
||||
```cpp |
||||
auto add = [](auto a, auto b) { return a + b; }; |
||||
auto sum_i = add(42, 13); // Still works with integers |
||||
auto sum_f = add(3.14, 2.72); // Now works with doubles too |
||||
``` |
||||
|
||||
- **Binary Literals**: Allow you to input integers as binary literals for better readability. |
||||
```cpp |
||||
int b = 0b110101; // Decimal value is 53 |
||||
``` |
||||
|
||||
- **decltype(auto)**: Deduces the type of variable to match that of the expression it is initialized with. |
||||
```cpp |
||||
auto func = [](auto a, auto b) { return a * b; }; |
||||
decltype(auto) result = func(5, 3.14); // decltype(auto) deduces to "double" |
||||
``` |
||||
|
||||
- **Variable Templates**: Allows you to define variables with template parameters. |
||||
```cpp |
||||
template <typename T> |
||||
constexpr T pi = T(3.1415926535897932385); |
||||
float r = pi<float>; // Instantiated as a float |
||||
double d = pi<double>; // Instantiated as a double |
||||
``` |
@ -1 +1,84 @@ |
||||
# Cpp20 |
||||
# C++20 |
||||
|
||||
C++20 is the latest standard of the C++ programming language, which brings significant improvements and new features to the language. This version is aimed at facilitating better software development practices and enabling developers to write more efficient, readable, and maintainable code. |
||||
|
||||
Here are some of the key features introduced in C++20: |
||||
|
||||
### Concepts |
||||
|
||||
Concepts are a way to enforce specific requirements on template parameters, allowing you to write more expressive and understandable code. They improve the error messages when using templates and ensure that the template parameters fulfill specific criteria. |
||||
|
||||
```cpp |
||||
template <typename T> |
||||
concept Addable = requires (T a, T b) { |
||||
{ a + b } -> std::same_as<T>; |
||||
}; |
||||
|
||||
template <Addable T> |
||||
T add(T a, T b) { |
||||
return a + b; |
||||
} |
||||
``` |
||||
|
||||
### Ranges |
||||
|
||||
Ranges provide a new way to work with sequences of values, enhancing the power and expressiveness of the Standard Library algorithms. The range-based algorithms make it easier and more convenient to work with sequences. |
||||
|
||||
```cpp |
||||
#include <algorithm> |
||||
#include <iostream> |
||||
#include <ranges> |
||||
#include <vector> |
||||
|
||||
int main() { |
||||
std::vector<int> numbers = { 1, 2, 3, 4, 5 }; |
||||
|
||||
auto even_numbers = numbers | std::views::filter([](int n) { return n % 2 == 0; }); |
||||
|
||||
for (int n : even_numbers) { |
||||
std::cout << n << ' '; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### Coroutines |
||||
|
||||
Coroutines are a new way to write asynchronous and concurrent code with improved readability. They allow functions to be suspended and resumed, enabling you to write more efficient, non-blocking code. |
||||
|
||||
```cpp |
||||
#include <coroutine> |
||||
#include <iostream> |
||||
#include <future> |
||||
|
||||
std::future<int> async_value(int value) { |
||||
co_await std::chrono::seconds(1); |
||||
co_return value * 2; |
||||
} |
||||
|
||||
int main() { |
||||
auto result = async_value(42); |
||||
std::cout << "Result: " << result.get() << std::endl; |
||||
} |
||||
``` |
||||
|
||||
### The `constexpr` and `consteval` Keywords |
||||
|
||||
Both `constexpr` and `consteval` are related to compile-time evaluation. Functions marked with `constexpr` can be executed at compile-time or runtime, while functions marked with `consteval` can only be executed at compile-time. |
||||
|
||||
```cpp |
||||
constexpr int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
|
||||
consteval int square(int x) { |
||||
return x * x; |
||||
} |
||||
|
||||
int main() { |
||||
constexpr int result1 = add(3, 4); // evaluated at compile-time |
||||
int result2 = add(5, 6); // evaluated at runtime |
||||
constexpr int result3 = square(7); // evaluated at compile-time |
||||
} |
||||
``` |
||||
|
||||
These are just some of the highlights of the C++20 standard. It also includes many other features and improvements, like structured bindings, improved lambdas, and new standard library components. Overall, C++20 makes it easier for developers to write clean, efficient, and expressive code. |
@ -1 +1,90 @@ |
||||
# Newest |
||||
# C++ Newest Standard: C++20 |
||||
|
||||
C++20 is the newest standard of the C++ programming language, which was officially published in December 2020. It introduces many new features, enhancements, and improvements over the previous standards. Here is a brief summary of some key features in C++20. |
||||
|
||||
1. **Concepts**: Concepts provide a way to specify constraints on template parameters, ensuring that they meet a specific set of requirements. This allows for better compile-time error messages and code readability. |
||||
|
||||
Example: |
||||
``` |
||||
template<typename T> |
||||
concept Printable = requires(T x) { |
||||
{std::cout << x}; |
||||
}; |
||||
|
||||
template<Printable T> |
||||
void print(const T& x) { |
||||
std::cout << x << '\n'; |
||||
} |
||||
``` |
||||
|
||||
2. **Ranges**: Ranges build on the iterator concept and provide a more usable and composable framework for dealing with sequences of values. They simplify the way algorithms can be applied to collections of data. |
||||
|
||||
Example: |
||||
``` |
||||
#include <iostream> |
||||
#include <vector> |
||||
#include <ranges> |
||||
|
||||
int main() { |
||||
std::vector<int> numbers{1, 2, 3, 4, 5}; |
||||
auto even_view = numbers | std::views::filter([](int n) { return n % 2 == 0; }); |
||||
|
||||
for (int n : even_view) { |
||||
std::cout << n << ' '; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
3. **Coroutines**: Coroutines offer a way to split complex, long-running functions into smaller, more manageable chunks, allowing them to be suspended and resumed at specific points. |
||||
|
||||
Example: |
||||
``` |
||||
#include <iostream> |
||||
#include <coroutine> |
||||
|
||||
std::generator<int> generator() { |
||||
for (int i = 0; i < 5; ++i) |
||||
co_yield i; |
||||
} |
||||
|
||||
int main() { |
||||
for (int value : generator()) |
||||
std::cout << value << ' '; |
||||
} |
||||
``` |
||||
|
||||
4. **Lambdas with template parameters**: C++20 enables using `auto` as a lambda parameter, allowing for generic lambdas with templated parameters. |
||||
|
||||
Example: |
||||
``` |
||||
auto sum = [](auto a, auto b) { |
||||
return a + b; |
||||
}; |
||||
|
||||
int res1 = sum(1, 2); // int |
||||
double res2 = sum(1.0, 2.0); // double |
||||
``` |
||||
|
||||
5. **Constexpr enhancements**: `constexpr` support is extended with additional features, such as `constexpr` dynamic allocations, `constexpr` try-catch blocks, and `constexpr` lambdas. |
||||
|
||||
Example: |
||||
``` |
||||
struct Point { |
||||
constexpr Point(int x, int y): x_{x}, y_{y} {} |
||||
int x_, y_; |
||||
}; |
||||
|
||||
constexpr auto create_points() { |
||||
Point points[3]{}; |
||||
|
||||
for (int i = 0; i < 3; ++i) { |
||||
points[i] = Point{i, i * i}; |
||||
} |
||||
|
||||
return points; |
||||
} |
||||
|
||||
constexpr auto points = create_points(); |
||||
``` |
||||
|
||||
There are many other features in C++20, such as new standard library improvements, `std::format`, improvements to compile-time programming, and more. These are just a few highlights that showcase the versatility and power of the newest standard of C++. |
@ -1 +1,63 @@ |
||||
# Standards |
||||
# C++ Standards |
||||
|
||||
C++ standards are a set of rules and guidelines that define the language's features, syntax, and semantics. The International Organization for Standardization (ISO) is responsible for maintaining and updating the C++ standards. The main purpose of the standards is to ensure consistency, efficiency, and maintainability across multiple platforms and compilers. |
||||
|
||||
Here's a brief summary of the different C++ standards released to date: |
||||
|
||||
1. **C++98/C++03**: The first standardized version of C++, which introduced many features like templates, exceptions, and the Standard Template Library (STL). C++03 is a minor update to C++98 with some bug fixes and performance improvements. |
||||
|
||||
2. **C++11**: A major upgrade to the language, which introduced features such as: |
||||
- Lambda expressions: |
||||
```cpp |
||||
auto sum = [](int a, int b) -> int { return a + b; }; |
||||
``` |
||||
- Range-based for loops: |
||||
```cpp |
||||
std::vector<int> numbers = {1, 2, 3, 4}; |
||||
for (int num : numbers) { |
||||
std::cout << num << std::endl; |
||||
} |
||||
``` |
||||
- Smart pointers like `std::shared_ptr` and `std::unique_ptr`. |
||||
|
||||
3. **C++14**: A minor update to C++11, which added features such as: |
||||
- Generic lambda expressions: |
||||
```cpp |
||||
auto generic_sum = [](auto a, auto b) { return a + b; }; |
||||
``` |
||||
- Binary literals: |
||||
```cpp |
||||
int binary_number = 0b1010; |
||||
``` |
||||
|
||||
4. **C++17**: Another major update that introduced features such as: |
||||
- `if` and `switch` with initializers: |
||||
```cpp |
||||
if (auto it = my_map.find(key); it != my_map.end()) { |
||||
// use 'it' here |
||||
} |
||||
``` |
||||
- Structured bindings: |
||||
```cpp |
||||
std::map<std::string, int> my_map = {{"A", 1}, {"B", 2}}; |
||||
for (const auto& [key, value] : my_map) { |
||||
// use 'key' and 'value' here |
||||
} |
||||
``` |
||||
|
||||
5. **C++20**: The latest major update to the language, with features such as: |
||||
- Concepts: |
||||
```cpp |
||||
template<typename T> |
||||
concept Addable = requires(T a, T b) { |
||||
{ a + b } -> std::same_as<T>; |
||||
}; |
||||
``` |
||||
- Ranges: |
||||
```cpp |
||||
std::vector<int> numbers = {1, 2, 3, 4}; |
||||
auto doubled = numbers | std::views::transform([](int n) { return n * 2; }); |
||||
``` |
||||
- Coroutines and more. |
||||
|
||||
Remember that to use these language features, you might need to configure your compiler to use the specific C++ standard version. For example, with GCC or Clang, you can use the `-std=c++11`, `-std=c++14`, `-std=c++17`, or `-std=c++20` flags. |
@ -1 +1,75 @@ |
||||
# Debugger messages |
||||
# Debugger Messages |
||||
|
||||
Debugger messages are notifications or alerts provided by a debugger to help you identify problems or errors in your C++ code. These messages can be warnings or error messages and can provide helpful information about the state of your program and specific issues encountered during the debugging process. |
||||
|
||||
### Types of Debugger Messages |
||||
|
||||
1. **Error Messages:** Notify you about issues in the code that prevent the program from running or compiling correctly. These messages typically include information about the file and the line number where the error is detected, followed by a description of the issue. |
||||
|
||||
Example: |
||||
``` |
||||
test.cpp: In function 'int main()': |
||||
test.cpp:6:5: error: 'cout' was not declared in this scope |
||||
cout << "Hello World!"; |
||||
^~~~ |
||||
``` |
||||
|
||||
2. **Warning Messages:** Inform you about potential issues or risky programming practices that may not necessarily cause errors but could lead to problems later on. Like error messages, warning messages usually include information about the file and line number where the issue is found, along with a description of the problem. |
||||
|
||||
Example: |
||||
``` |
||||
test.cpp: In function 'int main()': |
||||
test.cpp:6:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] |
||||
if (a < size) |
||||
^ |
||||
``` |
||||
|
||||
3. **Informational Messages:** Provide general information about the execution of the program, such as breakpoints, watchpoints, and variable values. These messages can also reveal the current state of the program, including the call stack and the list of active threads. |
||||
|
||||
Example (*assuming you are using GDB as debugger*): |
||||
``` |
||||
(gdb) break main |
||||
Breakpoint 1 at 0x40055f: file test.cpp, line 5. |
||||
(gdb) run |
||||
Starting program: /path/to/test |
||||
Breakpoint 1, main () at test.cpp:5 |
||||
5 int a = 5; |
||||
``` |
||||
### Code Examples |
||||
|
||||
To make use of debugger messages, you need to employ a debugger, such as GDB or Visual Studio Debugger, and include specific flags during the compilation process. |
||||
|
||||
Example using GDB: |
||||
|
||||
```cpp |
||||
// test.cpp |
||||
|
||||
#include <iostream> |
||||
using namespace std; |
||||
|
||||
int main() { |
||||
int num1 = 10; |
||||
int num2 = 0; |
||||
int result = num1 / num2; |
||||
|
||||
cout << "Result: " << result << endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
``` |
||||
$ g++ -g -o test test.cpp // Compile with -g flag to include debugging information |
||||
$ gdb ./test // Run the GDB debugger |
||||
(gdb) run // Execute the program inside GDB |
||||
``` |
||||
|
||||
At this point, the debugger will show an error message triggered by the division by zero: |
||||
|
||||
``` |
||||
Program received signal SIGFPE, Arithmetic exception. |
||||
0x00005555555546fb in main () at test.cpp:7 |
||||
7 int result = num1 / num2; |
||||
``` |
||||
|
||||
Now you can make appropriate changes to fix the issue in your C++ code. |
@ -1 +1,51 @@ |
||||
# Win dbg |
||||
# WinDbg |
||||
|
||||
WinDbg is a powerful debugger for Windows applications, which is included in the Microsoft Windows SDK. It provides an extensive set of features to help you analyze and debug complex programs, kernel mode, and user-mode code. With a user-friendly graphical interface, WinDbg can help in analyzing crash dumps, setting breakpoints, and stepping through code execution. |
||||
|
||||
### Getting Started |
||||
|
||||
To begin using WinDbg, you first need to install it. You can download the [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/) and install it to get the WinDbg. |
||||
|
||||
### Loading Symbols |
||||
|
||||
WinDbg relies on symbol files (*.pdb) to provide more useful information about a program's internal structures, functions, and variables. To load symbols properly, you may need to configure the symbol path: |
||||
|
||||
``` |
||||
!sym noisy |
||||
.sympath SRV*C:\symbols*http://msdl.microsoft.com/download/symbols |
||||
.reload /f |
||||
``` |
||||
|
||||
### Opening Executables and Crash Dumps |
||||
|
||||
To debug an executable using WinDbg, go to `File > Open Executable...`, then locate and open the target program. To analyze a crash dump, use `File > Open Crash Dump...` instead. |
||||
|
||||
### Basic Commands |
||||
|
||||
Some common commands you might use in WinDbg: |
||||
|
||||
- `g`: Execute the program until the next breakpoint or exception |
||||
- `bp <address>`: Set a breakpoint at a given address |
||||
- `bl`: List all breakpoints |
||||
- `bd <breakpoint_id>`: Disable a breakpoint |
||||
- `be <breakpoint_id>`: Enable a breakpoint |
||||
- `bc <breakpoint_id>`: Clear a breakpoint |
||||
- `t`: Single-step through instructions (trace) |
||||
- `p`: Step over instructions (proceed) |
||||
- `k`: Display call stack |
||||
- `dd`: Display memory contents in 4-byte units (double words) |
||||
- `da`: Display memory contents as ASCII strings |
||||
- `!analyze -v`: Analyze the program state and provide detailed information |
||||
|
||||
### Example Usage |
||||
|
||||
Debugging a simple program: |
||||
|
||||
1. Open the executable in WinDbg |
||||
2. Set a breakpoint using `bp <address>` |
||||
3. Run the program using `g` |
||||
4. Once the breakpoint is hit, use `t` or `p` to step through the code |
||||
5. Try `k` to view the call stack, or `dd`, `da` to inspect memory |
||||
6. Remove the breakpoint and continue debugging with other commands as needed |
||||
|
||||
Remember that WinDbg has a wealth of commands and functionality, so it's essential to get comfortable with the [documentation](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools) and explore the wealth of available resources specific to your debugging tasks. |
@ -1 +1,42 @@ |
||||
# Debuggers |
||||
# Debuggers |
||||
|
||||
Debuggers are essential tools for any C++ programmer, as they help in detecting, diagnosing, and fixing bugs in the code. They serve as an invaluable resource in identifying and understanding potential errors in the program. |
||||
|
||||
### Types of Debuggers |
||||
|
||||
There are several debuggers available for use with C++: |
||||
|
||||
1. **GDB (GNU Debugger):** This is the most widely used C++ debugger in the Linux environment. It can debug many languages, including C and C++. |
||||
|
||||
Example usage: |
||||
``` |
||||
g++ -g main.cpp -o main # compile the code with debug info |
||||
gdb ./main # start gdb session |
||||
b main # set a breakpoint at the start of the main function |
||||
run # run the program |
||||
next # step to the next line |
||||
``` |
||||
|
||||
2. **LLDB:** This is the debugger developed by LLVM. It supports multiple languages and is popular among macOS and iOS developers. |
||||
|
||||
Example usage: |
||||
``` |
||||
clang++ -g main.cpp -o main # compile the code with debug info |
||||
lldb ./main # start lldb session |
||||
breakpoint set --name main # set a breakpoint at the start of the main function |
||||
run # run the program |
||||
next # step to the next line |
||||
``` |
||||
|
||||
3. **Microsoft Visual Studio Debugger:** This debugger is built into Visual Studio and is typically used in a graphical interface on Windows systems. |
||||
|
||||
Example usage: |
||||
``` |
||||
Open your Visual Studio project and go to Debug > Start Debugging. Then use the step over (F10), step into (F11), or continue (F5) commands to navigate through the code. |
||||
``` |
||||
|
||||
4. **Intel Debugger (IDB):** This debugger is part of Intel's parallel development suite and is popular for high-performance applications. |
||||
|
||||
5. **TotalView Debugger:** Developed by Rogue Wave Software, TotalView Debugger is a commercial debugger designed for parallel, high-performance, and enterprise applications. |
||||
|
||||
Each debugger has its advantages and unique features, so it's essential to choose the one that best suits your needs and works well with your development environment. |
@ -1 +1,58 @@ |
||||
# Stages |
||||
# Stages of Compilation in C++ |
||||
|
||||
The process of compilation in C++ can be divided into four primary stages: Preprocessing, Compilation, Assembly, and Linking. Each stage performs a specific task, ultimately converting the source code into an executable program. |
||||
|
||||
### 1. Preprocessing |
||||
|
||||
The first stage is the preprocessing of the source code. Preprocessors modify the source code before the actual compilation process. They handle directives that start with a `#` (hash) symbol, like `#include`, `#define`, and `#if`. In this stage, included header files are expanded, macros are replaced, and conditional compilation statements are processed. |
||||
|
||||
**Code Example:** |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#define PI 3.14 |
||||
|
||||
int main() { |
||||
std::cout << "The value of PI is: " << PI << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### 2. Compilation |
||||
|
||||
The second stage is the actual compilation of the preprocessed source code. The compiler translates the modified source code into an intermediate representation, usually specific to the target processor architecture. This step also involves performing syntax checking, semantic analysis, and producing error messages for any issues encountered in the source code. |
||||
|
||||
**Code Example:** |
||||
|
||||
```cpp |
||||
int main() { |
||||
int a = 10; |
||||
int b = 20; |
||||
int sum = a + b; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### 3. Assembly |
||||
|
||||
The third stage is converting the compiler's intermediate representation into assembly language. This stage generates assembly code using mnemonics and syntax that is specific to the target processor architecture. Assemblers then convert this assembly code into object code (machine code). |
||||
|
||||
**Code Example (x86 Assembly):** |
||||
|
||||
```assembly |
||||
mov eax, 10 |
||||
mov ebx, 20 |
||||
add eax, ebx |
||||
``` |
||||
|
||||
### 4. Linking |
||||
|
||||
The final stage is the linking of the object code with the necessary libraries and other object files. In this stage, the linker merges multiple object files and libraries, resolves external references from other modules or libraries, allocates memory addresses for functions and variables, and generates an executable file that can be run on the target platform. |
||||
|
||||
**Code Example (linking objects and libraries):** |
||||
|
||||
```bash |
||||
$ g++ main.o -o main -lm |
||||
``` |
||||
|
||||
In summary, the compilation process in C++ involves four primary stages: preprocessing, compilation, assembly, and linking. Each stage plays a crucial role in transforming the source code into an executable program. |
@ -1 +1,86 @@ |
||||
# Features |
||||
# Features of C++ Compilers |
||||
|
||||
C++ compilers are responsible for transforming your human-readable C++ source code into machine-readable object code that can be executed by a computer. In this summary, we'll discuss different features of C++ compilers and, when applicable, provide code examples to illustrate them. |
||||
|
||||
1. **Standards compliance**: C++ compilers adhere to standard specifications set forth by ISO/IEC, ensuring that your code remains consistent across different platforms and operating systems. The most recent C++ standard is C++20. |
||||
|
||||
Example: |
||||
```cpp |
||||
// C++20 feature: concepts |
||||
template<typename T> |
||||
concept bool EqualityComparable = requires(T a, T b) { |
||||
{ a == b } -> bool; |
||||
{ a != b } -> bool; |
||||
}; |
||||
``` |
||||
|
||||
2. **Cross-compilation**: C++ compilers allow you to create executable files for various target platforms, even if your development environment is different. |
||||
|
||||
3. **Optimization**: C++ compilers can perform various optimization techniques to improve the performance or reduce the size of your compiled executable. |
||||
|
||||
Example: |
||||
```cpp |
||||
// Compiler will likely optimize this loop |
||||
int sum = 0; |
||||
for (int i = 0; i < 10; ++i) |
||||
sum += i; |
||||
``` |
||||
|
||||
4. **Header files and libraries**: C++ compilers include standard libraries and support inclusion of custom header files or third-party libraries, which provide additional utilities and functions. |
||||
|
||||
Example: |
||||
```cpp |
||||
#include <iostream> // Standard header for input/output operations |
||||
#include "custom_header.h" // Custom header |
||||
``` |
||||
|
||||
5. **Diagnostics**: C++ compilers produce diagnostic messages about errors or warnings in your source code to help you identify and fix issues. |
||||
|
||||
Example: |
||||
```cpp |
||||
int main() { |
||||
// Compiler will produce a diagnostic message |
||||
// about the missing semicolon |
||||
int a = 5 |
||||
int b = 10; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
6. **Debug and release configurations**: C++ compilers allow you to configure build settings for either debug or release mode, which helps you identify and fix bugs during development, or optimize your code for performance in the final version. |
||||
|
||||
7. **Templates**: C++ compilers support a robust template system that allows you to write generic code which works with different data types, without function or class duplication. |
||||
|
||||
Example: |
||||
```cpp |
||||
template<typename T> |
||||
T add(T a, T b) { |
||||
return a + b; |
||||
} |
||||
|
||||
int main() { |
||||
int result_int = add(1, 2); |
||||
double result_double = add(1.0, 2.0); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
8. **Language features**: C++ compilers support various language features, such as namespaces, classes, inheritance, polymorphism, exceptions, and more, making it possible to write clean, maintainable, and well-structured code. |
||||
|
||||
Example: |
||||
```cpp |
||||
// C++ class and inheritance example |
||||
class Animal { |
||||
public: |
||||
virtual void talk() const = 0; |
||||
}; |
||||
|
||||
class Dog : public Animal { |
||||
public: |
||||
void talk() const override { |
||||
std::cout << "Woof!" << std::endl; |
||||
} |
||||
}; |
||||
``` |
||||
|
||||
These are some of the key features you'll find in C++ compilers, which are essential for developing high-quality C++ applications efficiently. |
@ -1 +1,40 @@ |
||||
# Compilers |
||||
# Compilers |
||||
|
||||
A compiler is a computer program that translates source code written in one programming language into a different language, usually machine code or assembly code, that can be executed directly by a computer's processor. In the context of C++, compilers take your written C++ source code and convert it into an executable program. |
||||
|
||||
### Popular C++ Compilers |
||||
|
||||
There are several popular C++ compilers available, here's a short list of some common ones: |
||||
|
||||
1. **GNU Compiler Collection (GCC)**: Developed by the GNU Project, GCC is an open-source compiler that supports multiple programming languages, including C++. |
||||
|
||||
2. **Clang**: As part of the LLVM project, Clang is another open-source compiler that supports C++ and is known for its fast compilation times and extensive diagnostics. |
||||
|
||||
3. **Microsoft Visual C++ (MSVC)**: MSVC is a commercial compiler provided by Microsoft as part of Visual Studio, and it's widely used on Windows platforms. |
||||
|
||||
4. **Intel C++ Compiler (ICC)**: ICC is a commercial compiler provided by Intel and is known for its ability to optimize code for the latest Intel processors. |
||||
|
||||
### Example of a Simple C++ Compilation |
||||
|
||||
Let's say you have a simple C++ program saved in a file called `hello.cpp`: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::cout << "Hello, World!" << std::endl; |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
You can compile this program using the GCC compiler by executing the following command in a command-line/terminal: |
||||
|
||||
```bash |
||||
g++ hello.cpp -o hello |
||||
``` |
||||
|
||||
This will generate an executable file called `hello` (or `hello.exe` on Windows) which you can run to see the output "Hello, World!". |
||||
|
||||
### Note |
||||
|
||||
When learning about compilers, it's essential to know that they work closely with the linker and the standard library. The linker takes care of combining compiled object files and libraries into a single executable, while the standard library provides implementations for common functionalities used in your code. |
@ -1 +1,72 @@ |
||||
# Build systems |
||||
# Build Systems in C++ |
||||
|
||||
A build system is a collection of tools and utilities that automate the process of compiling, linking, and executing source code files in a project. The primary goal of build systems is to manage the complexity of the compilation process and produce a build (executable or binary files) in the end. In C++ (cpp), some common build systems are: |
||||
|
||||
1. **GNU Make**: It is a popular build system that uses `Makefile` to define the build process. It checks the dependencies and timestamps of source files to determine which files need to be compiled and linked. |
||||
|
||||
Code example: |
||||
|
||||
```Makefile |
||||
# Makefile |
||||
CXX = g++ |
||||
CPPFLAGS = -Wall -std=c++11 |
||||
TARGET = HelloWorld |
||||
|
||||
all: $(TARGET) |
||||
|
||||
$(TARGET): main.cpp |
||||
$(CXX) $(CPPFLAGS)main.cpp -o $(TARGET) |
||||
|
||||
clean: |
||||
rm $(TARGET) |
||||
``` |
||||
|
||||
2. **CMake**: It is a cross-platform build system that focuses on defining project dependencies and managing build environments. CMake generates build files (like Makefiles) for different platforms and allows developers to write source code once and then compile it for different target platforms. |
||||
|
||||
Code example: |
||||
|
||||
```CMake |
||||
# CMakeLists.txt |
||||
cmake_minimum_required(VERSION 3.10) |
||||
project(HelloWorld) |
||||
|
||||
set(CMAKE_CXX_STANDARD 11) |
||||
|
||||
add_executable(HelloWorld main.cpp) |
||||
``` |
||||
3. **Autotools**: Also known as GNU Build System, consists of the GNU Autoconf, Automake, and Libtool tools that enable developers to create portable software across different Unix-based systems. For a C++ project, you will need to create `configure.ac`, `Makefile.am` files with specific rules, and then run the following commands in the terminal to build the project: |
||||
|
||||
``` |
||||
autoreconf --install |
||||
./configure |
||||
make |
||||
make install |
||||
``` |
||||
|
||||
4. **SCons**: This build system uses Python for build scripts, making it more expressive than GNU Make. It can also build for multiple platforms and configurations simultaneously. |
||||
|
||||
Code example: |
||||
|
||||
``` |
||||
# SConstruct |
||||
env = Environment() |
||||
env.Program(target="HelloWorld", source=["main.cpp"]) |
||||
``` |
||||
|
||||
5. **Ninja**: A small and focused build system that takes a list of build targets specified in a human-readable text file and builds them as fast as possible. |
||||
|
||||
Code example: |
||||
|
||||
``` |
||||
# build.ninja |
||||
rule cc |
||||
command = g++ -c $in -o $out |
||||
|
||||
rule link |
||||
command = g++ $in -o $out |
||||
|
||||
build main.o: cc main.cpp |
||||
build HelloWorld: link main.o |
||||
default HelloWorld |
||||
``` |
||||
These are some of the popular build systems in C++, each with their own syntax and capabilities. While Make is widely used, CMake is a cross-platform build system that generates build files for other build systems like Make or Ninja. Autotools is suitable for creating portable software, SCons leverages Python for its build scripts, and Ninja focuses on fast build times. |
@ -1 +1,45 @@ |
||||
# Working with libs |
||||
# Working with Libraries in C++ |
||||
|
||||
When working with C++, you may need to use external libraries to assist in various tasks. Libraries are precompiled pieces of code that can be reused in your program to perform a specific task or provide a certain functionality. In C++, libraries can be either static libraries (.lib) or dynamic libraries (.dll in Windows, .so in Unix/Linux). |
||||
|
||||
**1. Static Libraries** |
||||
|
||||
Static libraries are incorporated into your program during compile time. They are linked with your code, creating a larger executable file, but it does not require any external files during runtime. |
||||
|
||||
To create a static library, you'll need to compile your source files into object files, then bundle them into an archive. You can use the following commands: |
||||
|
||||
``` |
||||
g++ -c sourcefile.cpp -o objectfile.o |
||||
ar rcs libmystaticlibrary.a objectfile.o |
||||
``` |
||||
|
||||
To use a static library, you need to include the header files in your source code and then link the library during the compilation process: |
||||
|
||||
``` |
||||
g++ main.cpp -o myprogram -L/path/to/your/library/ -lmystaticlibrary |
||||
``` |
||||
|
||||
Replace `/path/to/your/library/` with the path where your `libmystaticlibrary.a` file is located. |
||||
|
||||
**2. Dynamic Libraries** |
||||
|
||||
Dynamic libraries are loaded during runtime, which means that your executable file only contains references to these libraries. The libraries need to be available on the system where your program is running. |
||||
|
||||
To create a dynamic library, you'll need to compile your source files into object files, then create a shared library: |
||||
|
||||
``` |
||||
g++ -c -fPIC sourcefile.cpp -o objectfile.o |
||||
g++ -shared -o libmydynamiclibrary.so objectfile.o |
||||
``` |
||||
|
||||
To use a dynamic library, include the library's header files in your source code and then link the library during the compilation process: |
||||
|
||||
``` |
||||
g++ main.cpp -o myprogram -L/path/to/your/library/ -lmydynamiclibrary |
||||
``` |
||||
|
||||
Replace `/path/to/your/library/` with the path where your `libmydynamiclibrary.so` file is located. |
||||
|
||||
**NOTE:** When using dynamic libraries, make sure the library is in the system's search path for shared libraries. You may need to update the `LD_LIBRARY_PATH` environment variable on Unix/Linux systems or the `PATH` variable on Windows. |
||||
|
||||
In conclusion, using libraries in C++ involves creating or obtaining a library (static or dynamic), including the library's header files in your source code, and linking the library during the compilation process. Be aware of the differences between static and dynamic libraries, and choose the right approach to suit your needs. |
@ -1 +1,75 @@ |
||||
# Gtest |
||||
# Google Test (gtest) |
||||
|
||||
Google Test, also known as gtest or googletest, is a C++ testing framework developed by Google. It provides a user-friendly API for writing test cases and is designed for use in a range of applications, from simple unit tests to complex system-level tests. |
||||
|
||||
### Getting Started with Google Test |
||||
|
||||
To use Google Test in your project, follow these steps: |
||||
|
||||
1. Download the source code from the [GoogleTest GitHub repository](https://github.com/google/googletest). |
||||
2. Build and install Google Test on your system. Instructions for various platforms can be found in the [README](https://github.com/google/googletest/blob/master/googletest/README.md) file. |
||||
3. Include the necessary headers and link against the Google Test library in your project. |
||||
|
||||
### Writing a Test with Google Test |
||||
|
||||
Here's an example of how to write a simple test using Google Test: |
||||
|
||||
1. **Include the necessary headers** |
||||
```cpp |
||||
#include "gtest/gtest.h" |
||||
``` |
||||
|
||||
2. **Write the functions you want to test** |
||||
|
||||
Suppose we have a simple function to test: |
||||
```cpp |
||||
int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
``` |
||||
|
||||
3. **Write the test cases** |
||||
|
||||
To create a test case, use the `TEST()` macro, which takes two arguments: the test suite name and the test case name. |
||||
|
||||
```cpp |
||||
// Test the 'add' function. |
||||
TEST(AdditionTest, PositiveNumbers) { |
||||
EXPECT_EQ(3, add(1, 2)); |
||||
EXPECT_EQ(5, add(2, 3)); |
||||
} |
||||
|
||||
TEST(AdditionTest, NegativeNumbers) { |
||||
EXPECT_EQ(-3, add(-1, -2)); |
||||
EXPECT_EQ(-5, add(-2, -3)); |
||||
} |
||||
``` |
||||
|
||||
4. **Write a `main()` function** |
||||
|
||||
In order to run the tests, include a `main()` function that initializes Google Test and runs the tests. |
||||
|
||||
```cpp |
||||
int main(int argc, char **argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
||||
``` |
||||
|
||||
5. **Compile and run the tests** |
||||
|
||||
Compile your test program with the Google Test library and run the test executable. |
||||
|
||||
### More Features |
||||
|
||||
Google Test offers a wide range of features to make testing easier, such as: |
||||
|
||||
- **Test Fixtures**: Test fixtures allow you to reuse the same set of objects for multiple tests. You can define a test fixture by creating a class that inherits from `::testing::Test` and writing setup and teardown methods. |
||||
|
||||
- **Assertions**: Google Test provides a variety of assertion macros to help you verify your code's behavior. Some common ones include `EXPECT_EQ`, `EXPECT_TRUE`, `EXPECT_FALSE`, `ASSERT_EQ`, `ASSERT_TRUE`, and `ASSERT_FALSE`. |
||||
|
||||
- **Parameterized Tests**: Google Test supports parameterized tests, allowing you to run the same test with different inputs easily. |
||||
|
||||
- **Death Tests**: Google Test allows you to write tests that verify if your code terminates correctly or with the expected error message. |
||||
|
||||
For more information about Google Test and its features, refer to the [official documentation](https://github.com/google/googletest/blob/master/googletest/docs/primer.md). |
@ -1 +1,96 @@ |
||||
# Catch2 |
||||
# Catch2 |
||||
|
||||
Catch2 is a modern, C++-native, test framework for unit tests, TDD, and BDD. It is a single-header library, meaning you only need to include one header file (`catch.hpp`) to start using it. Catch2 is fast, easy to use, and supports various test styles. |
||||
|
||||
## Features |
||||
|
||||
- **Single-header:** Just `#include "catch.hpp"` and start writing tests. |
||||
- **Test cases:** Declare test cases using the `TEST_CASE` macro. |
||||
- **Sections:** Divide test cases into sections using `SECTION` macro. |
||||
- **BDD:** Behavior-Driven Development style supported with `SCENARIO`, `GIVEN`, `WHEN`, `THEN`. |
||||
- **Matchers:** Use rich built-in matchers for more expressive assertions. |
||||
- **Test discovery:** Catch2 automatically discovers your test cases and sections. |
||||
|
||||
## Code examples |
||||
|
||||
### Basic test case |
||||
|
||||
```cpp |
||||
#define CATCH_CONFIG_MAIN // Tells Catch to provide a main() function |
||||
#include "catch.hpp" |
||||
|
||||
int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
|
||||
TEST_CASE("Addition") { |
||||
REQUIRE(add(2, 3) == 5); |
||||
} |
||||
``` |
||||
|
||||
### Sections |
||||
|
||||
```cpp |
||||
TEST_CASE("Sections example") { |
||||
int a = 1; |
||||
|
||||
SECTION("incrementing a") { |
||||
a++; |
||||
REQUIRE(a == 2); |
||||
} |
||||
|
||||
SECTION("decrementing a") { |
||||
a--; |
||||
REQUIRE(a == 0); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### BDD style |
||||
|
||||
```cpp |
||||
SCENARIO("vector can be sized and resized", "[vector]") { |
||||
std::vector<int> v; |
||||
|
||||
GIVEN("A vector with some items") { |
||||
v.push_back(1); |
||||
v.push_back(2); |
||||
v.push_back(3); |
||||
|
||||
REQUIRE(v.size() == 3); |
||||
|
||||
WHEN("the size is increased") { |
||||
v.resize(5); |
||||
|
||||
THEN("the size and contents change") { |
||||
REQUIRE(v.size() == 5); |
||||
REQUIRE(v[3] == 0); |
||||
REQUIRE(v[4] == 0); |
||||
} |
||||
} |
||||
WHEN("the size is reduced") { |
||||
v.resize(2); |
||||
|
||||
THEN("the size changes but not the contents") { |
||||
REQUIRE(v.size() == 2); |
||||
REQUIRE(v[0] == 1); |
||||
REQUIRE(v[1] == 2); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### Matchers |
||||
|
||||
```cpp |
||||
TEST_CASE("Matchers example") { |
||||
std::string str = "Hello, world!"; |
||||
|
||||
CHECK_THAT(str, Catch::Matchers::StartsWith("Hello")); |
||||
CHECK_THAT(str, Catch::Matchers::EndsWith("world!")); |
||||
CHECK_THAT(str, Catch::Matchers::Contains("lo, wo")); |
||||
} |
||||
``` |
||||
|
||||
For more information, visit the [Catch2 GitHub repository](https://github.com/catchorg/Catch2). |
@ -1 +1,71 @@ |
||||
# Pytorch cpp |
||||
# PyTorch C++ |
||||
|
||||
PyTorch C++ is the C++ API (Application Programming Interface) for PyTorch. It is also known as LibTorch, which is a library that provides almost all the functionality of PyTorch accessible through C++ language. The main goal of providing a C++ API is to enable high-performance integration with other deep learning platforms and enable seamless operation in enterprise and production-level systems. |
||||
|
||||
### Installation |
||||
|
||||
To use the PyTorch C++ API, you need to install the LibTorch distribution. Follow the instructions on the [official PyTorch C++ API page](https://pytorch.org/cppdocs/installing.html) to install the library based on your platform and requirements. |
||||
|
||||
### Example: Tensors |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <torch/torch.h> |
||||
|
||||
int main() { |
||||
// Create a 3x3 matrix with zeros. |
||||
torch::Tensor a = torch::zeros({3, 3}); |
||||
std::cout << a << std::endl; |
||||
|
||||
// Create a 2x2 matrix with ones and convert to float. |
||||
torch::Tensor b = torch::ones({2, 2}).to(torch::kFloat); |
||||
std::cout << b << std::endl; |
||||
|
||||
// Create a random tensor size 2x2 and specify its type. |
||||
torch::Tensor c = torch::randint(0, 10, {2, 2}, torch::kInt); |
||||
std::cout << c << std::endl; |
||||
|
||||
// Perform element-wise addition. |
||||
auto sum = b + c.to(torch::kFloat); |
||||
std::cout << sum << std::endl; |
||||
} |
||||
``` |
||||
|
||||
### Example: Creating a Custom Module |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <torch/torch.h> |
||||
|
||||
// Define a custom module. |
||||
struct Net : torch::nn::Module { |
||||
Net() { |
||||
fc1 = register_module("fc1", torch::nn::Linear(784, 64)); |
||||
fc2 = register_module("fc2", torch::nn::Linear(64, 10)); |
||||
} |
||||
|
||||
torch::Tensor forward(torch::Tensor x) { |
||||
x = x.view({-1, 784}); |
||||
x = torch::relu(fc1->forward(x)); |
||||
x = torch::log_softmax(fc2->forward(x), 1); |
||||
return x; |
||||
} |
||||
|
||||
torch::nn::Linear fc1{nullptr}; |
||||
torch::nn::Linear fc2{nullptr}; |
||||
}; |
||||
|
||||
int main() { |
||||
// Create an instance of the custom module. |
||||
Net net; |
||||
|
||||
// Use the custom module. |
||||
torch::Tensor input = torch::randn({2, 1, 28, 28}); |
||||
torch::Tensor output = net.forward(input); |
||||
std::cout << output << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
In these examples, we demonstrated how to use various tensor operations and how to create a custom neural network module with PyTorch C++. For more detailed information and tutorials, visit the [official PyTorch C++ documentation](https://pytorch.org/cppdocs/). |
@ -1 +1,79 @@ |
||||
# Protobuf |
||||
# Protocol Buffers (protobuf) |
||||
|
||||
Protocol Buffers, or protobuf, is a language and platform-neutral data serialization format developed by Google. It is used to efficiently serialize structured data for use in communications protocols, data storage, and more. It is extensible, as it allows you to define your own custom data structures called "messages" with various scalar and complex field types. |
||||
|
||||
Here is a brief summary of protobuf and how to use it in C++: |
||||
|
||||
1. **Define your `.proto` file:** Create a `.proto` file that defines the structure of your messages. |
||||
|
||||
*Example:* |
||||
|
||||
```protobuf |
||||
syntax = "proto3"; |
||||
|
||||
message Person { |
||||
string name = 1; |
||||
int32 age = 2; |
||||
string email = 3; |
||||
} |
||||
``` |
||||
|
||||
2. **Compile the `.proto` file:** You need to compile your `.proto` file to generate C++ classes for serialization and deserialization. |
||||
|
||||
*Example:* |
||||
|
||||
```sh |
||||
protoc --cpp_out=. person.proto |
||||
``` |
||||
|
||||
This will generate two files: `person.pb.cc` and `person.pb.h` that contains the C++ class definitions. |
||||
|
||||
3. **Include protobuf library and generated files into your C++ code:** You'll need to include the protobuf library and the generated files in your main C++ code. |
||||
|
||||
*Example:* |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include "person.pb.h" |
||||
|
||||
int main () { |
||||
GOOGLE_PROTOBUF_VERIFY_VERSION; // Verify that protobuf library headers match library version |
||||
|
||||
// Serialize a Person message |
||||
Person person; |
||||
person.set_name("Sam"); |
||||
person.set_age(35); |
||||
person.set_email("sam@example.com"); |
||||
|
||||
// Save the data to a file |
||||
std::ofstream output("person.bin", ios::binary); |
||||
person.SerializeToOstream(&output); |
||||
output.close(); |
||||
|
||||
// Deserialize the message from the file |
||||
Person input_person; |
||||
std::ifstream input("person.bin", ios::binary); |
||||
input_person.ParseFromIstream(&input); |
||||
input.close(); |
||||
|
||||
// Print the deserialized message |
||||
std::cout << "Name: " << input_person.name() << std::endl; |
||||
std::cout << "Age: " << input_person.age() << std::endl; |
||||
std::cout << "Email: " << input_person.email() << std::endl; |
||||
|
||||
google::protobuf::ShutdownProtobufLibrary(); |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
4. **Compile and link your C++ code:** Finally, compile your C++ code and link it to the protobuf library. |
||||
|
||||
*Example:* |
||||
|
||||
```sh |
||||
g++ -std=c++11 -o main main.cpp person.pb.cc -lprotobuf |
||||
``` |
||||
|
||||
For more information and examples, you can refer to the [official protobuf C++ tutorial](https://developers.google.com/protocol-buffers/docs/cpptutorial). |
@ -1 +1,129 @@ |
||||
# Grpc |
||||
# gRPC |
||||
|
||||
gRPC (gRPC Remote Procedure Calls) is an open-source Remote Procedure Call (RPC) framework that runs on various programming languages, including C++. gRPC is designed to be high-performance, efficient, and scalable, making it ideal for microservice architectures and other applications with high performance requirements. |
||||
|
||||
gRPC uses the Protocol Buffers (Protobuf) serialization format for message exchange and method definition. Protocol Buffers enable more efficient and smaller serialization compared to other formats like JSON or XML. |
||||
|
||||
### Protocol Buffers |
||||
|
||||
In gRPC, you start by defining service definitions and message structures in `.proto` files. You can define data structures and service interfaces using a compact, language-neutral, platform-neutral binary format. |
||||
|
||||
Here's an example of how that might look: |
||||
|
||||
```protobuf |
||||
syntax = "proto3"; |
||||
|
||||
package example; |
||||
|
||||
// The gRPC service definition |
||||
service Greeter { |
||||
rpc SayHello (HelloRequest) returns (HelloReply) {} |
||||
} |
||||
|
||||
// The Request message definition |
||||
message HelloRequest { |
||||
string name = 1; |
||||
} |
||||
|
||||
// The Reply message definition |
||||
message HelloReply { |
||||
string message = 1; |
||||
} |
||||
``` |
||||
|
||||
After defining the `.proto` file, you use the `protoc` compiler to generate the corresponding C++ code for your application. |
||||
|
||||
### gRPC C++ Server |
||||
|
||||
To create a gRPC server in C++, you first need to implement the service interface generated by the `protoc` compiler. Here's an example implementation for the `Greeter` service: |
||||
|
||||
```cpp |
||||
#include <grpcpp/grpcpp.h> |
||||
#include "example.grpc.pb.h" |
||||
|
||||
using grpc::Server; |
||||
using grpc::ServerBuilder; |
||||
using grpc::ServerContext; |
||||
using grpc::Status; |
||||
using example::HelloRequest; |
||||
using example::HelloReply; |
||||
using example::Greeter; |
||||
|
||||
class GreeterServiceImpl final : public Greeter::Service { |
||||
Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { |
||||
std::string prefix("Hello "); |
||||
reply->set_message(prefix + request->name()); |
||||
return Status::OK; |
||||
} |
||||
}; |
||||
|
||||
void RunServer() { |
||||
std::string server_address("0.0.0.0:50051"); |
||||
GreeterServiceImpl service; |
||||
|
||||
ServerBuilder builder; |
||||
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); |
||||
builder.RegisterService(&service); |
||||
|
||||
std::unique_ptr<Server> server(builder.BuildAndStart()); |
||||
std::cout << "Server listening on " << server_address << std::endl; |
||||
server->Wait(); |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
RunServer(); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### gRPC C++ Client |
||||
|
||||
Similarly, to create a gRPC C++ client, you use the generated code from `protoc` compiler and connect to a server: |
||||
|
||||
```cpp |
||||
#include <grpcpp/grpcpp.h> |
||||
#include "example.grpc.pb.h" |
||||
|
||||
using grpc::Channel; |
||||
using grpc::ClientContext; |
||||
using grpc::Status; |
||||
using example::HelloRequest; |
||||
using example::HelloReply; |
||||
using example::Greeter; |
||||
|
||||
class GreeterClient { |
||||
public: |
||||
GreeterClient(std::shared_ptr<Channel> channel) : stub_(Greeter::NewStub(channel)) {} |
||||
|
||||
std::string SayHello(const std::string& user) { |
||||
HelloRequest request; |
||||
request.set_name(user); |
||||
|
||||
HelloReply reply; |
||||
ClientContext context; |
||||
|
||||
Status status = stub_->SayHello(&context, request, &reply); |
||||
|
||||
if (status.ok()) { |
||||
return reply.message(); |
||||
} else { |
||||
std::cout << "RPC failed" << std::endl; |
||||
return "RPC failed"; |
||||
} |
||||
} |
||||
|
||||
private: |
||||
std::unique_ptr<Greeter::Stub> stub_; |
||||
}; |
||||
|
||||
int main(int argc, char** argv) { |
||||
GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials())); |
||||
std::string user("world"); |
||||
std::string reply = greeter.SayHello(user); |
||||
std::cout << "Greeter received: " << reply << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
This is a basic example demonstrating the client-server communication using gRPC in C++. More advanced features like bi-directional streaming, error handling, and authentication can also be used in gRPC. For more information, you can refer to the [gRPC C++ documentation](https://grpc.io/docs/languages/cpp/). |
@ -1 +1,70 @@ |
||||
# Pybind11 |
||||
# Pybind11 |
||||
|
||||
Pybind11 is a lightweight header-only library that seamlessly integrates C++ code with Python, allowing users to easily expose C++11 code to the Python ecosystem. This is achieved by providing `Python` bindings that can interact with functions and classes written in `C++`. It offers an API similar to the Boost.Python library but requires less code, thus leading to better performance. |
||||
|
||||
Pybind11 helps in creating library extensions, bringing high-performance C++ code into Python programs, and using Python's flexibility for rapid development while still benefiting from the efficiency of C++. |
||||
|
||||
#### Code Examples |
||||
|
||||
Here are a few examples of Pybind11 for understanding the concept better: |
||||
|
||||
- Exposing a C++ function to Python: |
||||
|
||||
```cpp |
||||
#include <pybind11/pybind11.h> |
||||
|
||||
int add(int a, int b) { |
||||
return a + b; |
||||
} |
||||
|
||||
PYBIND11_MODULE(example, m) { |
||||
m.def("add", &add, "A function that adds two numbers"); |
||||
} |
||||
``` |
||||
|
||||
Running the above example will create a Python module named `example`, containing a single function `add`. You can use this new function in Python as follows: |
||||
|
||||
```python |
||||
import example |
||||
|
||||
result = example.add(1, 2) |
||||
print(result) # Output: 3 |
||||
``` |
||||
|
||||
- Exposing a C++ class to Python: |
||||
|
||||
```cpp |
||||
#include <pybind11/pybind11.h> |
||||
|
||||
namespace py = pybind11; |
||||
|
||||
class MyTestClass { |
||||
public: |
||||
MyTestClass(const std::string &name) : name_(name) { } |
||||
|
||||
const std::string &name() const { return name_; } |
||||
void setName(const std::string &name) { name_ = name; } |
||||
|
||||
private: |
||||
std::string name_; |
||||
}; |
||||
|
||||
PYBIND11_MODULE(example, m) { |
||||
py::class_<MyTestClass>(m, "MyTestClass") |
||||
.def(py::init<const std::string &>()) |
||||
.def("name", &MyTestClass::name) |
||||
.def("setName", &MyTestClass::setName); |
||||
} |
||||
``` |
||||
|
||||
After compiling the code and importing it into Python, you can create `MyTestClass` instances and call their `name()` and `setName(string)` methods: |
||||
|
||||
```python |
||||
import example |
||||
|
||||
obj = example.MyTestClass("some_name") |
||||
print(obj.name()) # Output: some_name |
||||
|
||||
obj.setName("new_name") |
||||
print(obj.name()) # Output: new_name |
||||
``` |
@ -1 +1,59 @@ |
||||
# Opencl |
||||
# OpenCL |
||||
|
||||
OpenCL (Open Computing Language) is a framework for writing programs that enables you to execute code on heterogeneous platforms consisting of CPUs, GPUs, and other processors. It is primarily used for parallel programming, and it can be employed to improve the performance of various applications, including gaming, image and video rendering, and scientific computing. |
||||
|
||||
### Overview |
||||
|
||||
OpenCL provides a standardized programming interface, allowing you to target different devices such as graphics cards from different vendors. You can program in C with OpenCL C or C++ with OpenCL C++ kernel language, which are based on the ISO C99 and C++14 respectively, with specific extensions, built-ins, and features to exploit device parallelism. |
||||
|
||||
### Key Concepts |
||||
|
||||
1. Platform: A collection of devices and software features provided by a vendor. |
||||
2. Device: A processing unit that can execute OpenCL code, e.g., a CPU or a GPU. |
||||
3. Command queue: A sequence of instructions to be executed on a device. |
||||
4. Kernel: A parallelized function that is executed on OpenCL devices. |
||||
5. Buffer: A memory object that stores a specific amount of data (e.g., an array of integers or floats) that is accessible by both the host and devices. |
||||
|
||||
### Sample Code |
||||
|
||||
Here is a simple OpenCL code example that illustrates how to implement vector addition: |
||||
|
||||
```cpp |
||||
#include <CL/cl.h> |
||||
#include <iostream> |
||||
#include <vector> |
||||
|
||||
const char *kernelSource = "__kernel void vector_add(__global int *A, __global int *B, __global int *C, const int N){" |
||||
" int i = get_global_id(0);" |
||||
" if(i < N){" |
||||
" C[i] = A[i] + B[i];" |
||||
" }" |
||||
"}"; |
||||
|
||||
int main(){ |
||||
// Initialize data vectors |
||||
std::vector<int> A = {1, 2, 3}; |
||||
std::vector<int> B = {4, 5, 6}; |
||||
std::vector<int> C(A.size()); |
||||
|
||||
// Set up OpenCL environment, devices, and context |
||||
// ... omitted for brevity ... |
||||
|
||||
// Create memory buffers for A, B, and C |
||||
// ... omitted for brevity ... |
||||
|
||||
// Create kernel from source and set kernel arguments |
||||
// ... omitted for brevity ... |
||||
|
||||
// Execute kernel using command queue and read output buffer |
||||
// ... omitted for brevity ... |
||||
|
||||
// Output results |
||||
for (size_t i = 0; i < A.size(); ++i) { |
||||
std::cout << A[i] << " + " << B[i] << " = " << C[i] << std::endl; |
||||
} |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
This code snippet demonstrates the basic structure of an OpenCL program in C++. There are additional details required in order to set up the environment, devices, and context, as well as creating the memory buffers, kernel, and command queue. You can find complete examples and more information in the [official OpenCL Programming Guide](https://www.khronos.org/files/opencl22-reference-guide.pdf). |
@ -1 +1,84 @@ |
||||
# Ranges v3 |
||||
# Ranges v3 |
||||
|
||||
Ranges v3 is a C++ library designed to work with ranges of values, rather than individual values. It provides a set of utilities and algorithms to manipulate and transform ranges of values in an efficient and expressive way. The library is inspired by the Range concept proposed for inclusion in the C++ standard library for C++20. |
||||
|
||||
--- |
||||
|
||||
## Overview |
||||
|
||||
Ranges v3 includes three main components: |
||||
|
||||
1. **Range adaptors:** These are composable algorithms that transform a range into a new range. They help to create lazy views over the data without actually modifying it. |
||||
|
||||
2. **Action adaptors:** These are algorithms that modify a range in-place. For example, sorting or filtering elements in a container directly. |
||||
|
||||
3. **Trait concepts and utility functions:** Provide tools for working with range types, like determining if a type is a range, getting the iterator type for a range, etc. |
||||
|
||||
--- |
||||
|
||||
## Code examples |
||||
|
||||
Here are some code examples of using the Ranges v3 library: |
||||
|
||||
### Including the library |
||||
|
||||
First, you need to include the appropriate header files from the library. To use the entire Ranges v3 library, you can simply include the `range/v3/all.hpp` header file: |
||||
|
||||
```cpp |
||||
#include <range/v3/all.hpp> |
||||
``` |
||||
|
||||
### Using range adaptors |
||||
|
||||
You can use range adaptors to manipulate and transform ranges. For example, you can use the `view::filter` and `view::transform` adaptors to create a new range containing only even numbers and then square them: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <range/v3/all.hpp> |
||||
|
||||
using namespace ranges; |
||||
|
||||
int main() { |
||||
std::vector<int> numbers = {1, 2, 3, 4, 5, 6}; |
||||
|
||||
// Create a new range containing only even numbers, and then square them. |
||||
auto even_squares = numbers | view::filter([](int n) { return n % 2 == 0; }) |
||||
| view::transform([](int n) { return n * n; }); |
||||
|
||||
// Print the even_squares range. |
||||
for (auto n : even_squares) { |
||||
std::cout << n << ' '; |
||||
} |
||||
// Output: 4 16 36 |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
### Using action adaptors |
||||
|
||||
Action adaptors are used to modify ranges in-place. For example, you can use the `action::sort` and `action::unique` adaptors to sort and remove duplicate elements from a container: |
||||
|
||||
```cpp |
||||
#include <iostream> |
||||
#include <range/v3/all.hpp> |
||||
|
||||
using namespace ranges; |
||||
|
||||
int main() { |
||||
std::vector<int> numbers = {5, 3, 1, 4, 4, 2, 2}; |
||||
|
||||
// Sort the numbers and remove duplicates. |
||||
numbers |= action::sort | action::unique; |
||||
|
||||
// Print the modified numbers vector. |
||||
for (auto n : numbers) { |
||||
std::cout << n << ' '; |
||||
} |
||||
// Output: 1 2 3 4 5 |
||||
|
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
Ranges v3 provides a wide range of adaptors and actions to work with ranges in a more expressive and efficient way. You can explore more in the [official documentation](https://github.com/ericniebler/range-v3/blob/master/doc/index.md). |
Loading…
Reference in new issue