-
Notifications
You must be signed in to change notification settings - Fork 1
/
references.hpp
199 lines (155 loc) · 10 KB
/
references.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#ifndef __REFERENCES_H
#define __REFERENCES_H
#include <iostream>
#include <iomanip>
#include <ios>
#include <array>
#include <new>
#include <ctime>
#include <cstdlib>
#include <cstdint>
#include <climits>
#include <bitset>
using namespace std;
/*
- References are Just Aliases:
- Simple Meaning:
- A reference in C++ is like a nickname or an alias for an existing variable.
- It's another name that can be used to refer to the same value or object.
- When you modify the reference, you are actually modifying the original variable.
- References are often used to avoid making copies of objects or to allow functions to modify variables directly.
- Deep Meaning:
- The deep meaning of references in C++ goes beyond just providing alternative names for variables. Here are some key aspects:
- Object Identity: References allow you to create multiple names that refer to the same object in memory. They establish a relationship between the reference and the original object, providing a way to access and modify the object through different names.
- Avoiding Copies: When you pass objects by value in C++, a copy of the object is made, which can be inefficient for large objects. By using references as function parameters, you can avoid this overhead. Changes made to the reference inside the function directly affect the original object.
- Efficiency: References provide a way to work with large objects or complex data structures without incurring the memory and time costs of copying them. They allow you to pass objects to functions without duplicating the data, which can be especially important when dealing with performance-critical code.
- Modifying Objects: References allow functions to modify the original object directly. This is particularly useful when you want a function to have the ability to change the state of an object passed to it as a parameter. By using references, you can avoid the need for returning values or using pointers explicitly.
- Aliasing: References can be used to create aliases for variables, enabling you to work with multiple names for the same value. This can enhance code readability and expressiveness, as well as facilitate the use of complex data structures where different parts of the program need to refer to the same object.
- Overall, references in C++ provide a powerful mechanism for efficient and flexible manipulation of objects, enabling you to work with complex data structures, avoid unnecessary copies, and directly modify objects. They contribute to the overall performance, clarity, and maintainability of your code.
- Syntax:
- type& ref_name { original_var };
- Ex:
int original_var { 100 };
int& ref_to_original_var { original_var }; // Normal Reference
const int& const_ref_to_original_var { original_var }; // Constant Reference
- Notes:
- Any changes made to 'ref_to_original_var' will be reflected in 'original_var' since they refer to the same memory location.
- Modifying 'ref_to_original_var' to 20 updates the value of 'original_var' accordingly.
- References can be declared as const references, where the referenced object cannot be modified through the reference.
- In this case, 'const_ref_to_original_var' is a constant reference to 'original_var', meaning that you can read the value of 'original_var' through constRef, but you cannot modify 'original_var' through 'const_ref_to_original_var'.
- Remember that references in C++ are different from pointers.
- Once a reference is bound to an object, it behaves like an alias for that object, whereas pointers can be reassigned to point to different objects.
- Comparison of references and pointers in C++:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| References | Pointers
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Declaration Must be initialized upon declaration Can be declared without initialization
Syntax type& referenceName = originalVariable; type* pointerName = nullptr;
Reassignment Cannot be reassigned to refer to a different object Can be reassigned to point to different objects
Nullability Cannot be null Can be set to null (nullptr) or point to valid objects
Indirection Automatically dereferenced when accessing the referenced object Must be explicitly dereferenced using the * operator
Address-of operator Not applicable Uses the & operator to obtain the address of an object
Arithmetic operations Not applicable Supports arithmetic operations (pointer arithmetic)
Function parameters Can be used to pass arguments by reference Can be used to pass arguments by value or reference
Memory management Automatically handled by the language Requires manual memory allocation and deallocation
Size Generally same size as the referenced object Generally same size as a pointer (4 or 8 bytes)
Safety Provides more safety as they cannot be null or uninitialized May have null or uninitialized values, potential for nullptr dereference or memory errors
Use cases Preferred for aliasing, function parameters, avoiding copies Used for dynamic memory allocation, passing by reference, or allowing null values
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Summary:
- It's important to note that both references and pointers have their own use cases and situations where they are more appropriate.
References are commonly used for aliasing variables and passing parameters by reference,
while pointers are often used for dynamic memory allocation, creating data structures, or allowing null values.
Choosing between references and pointers depends on the specific requirements and design of your program.
*/
void references()
{
int score = 10;
// reference to score
int& ref_to_score { score };
std::cout << "# Before Modifying: ------------------------------------" << std::endl << std::endl;
std::cout << "\tOriginal Variable Information: " << std::endl;
std::cout
<< "\t\tscore Address:\t\t\t"
<< &score
<< std::endl
<< "\t\tscore value:\t\t\t"
<< score
<< std::endl
<< "\t\tscore Size:\t\t\t\t"
<< sizeof(score)
<< std::endl
<< std::endl;
std::cout << "\tReference Information: " << std::endl;
std::cout
<< "\t\tref_to_score Address:\t"
<< &ref_to_score
<< std::endl
<< "\t\tref_to_score value:\t\t"
<< ref_to_score
<< std::endl
<< "\t\tref_to_score& Size:\t\t"
<< sizeof(ref_to_score)
<< std::endl
<< std::endl;
std::cout << std::endl;
std::cout << "# After Modifying with reference: ------------------------------------" << std::endl << std::endl;
std::cout << "\tOriginal Variable Information: " << std::endl;
// Modifying the references will affect on the original variable and vice versa
ref_to_score = 8989;
// After Modifying
std::cout
<< "\t\tscore Address:\t\t\t"
<< &score
<< std::endl
<< "\t\tscore value:\t\t\t"
<< score
<< std::endl
<< "\t\tscore Size:\t\t\t\t"
<< sizeof(score)
<< std::endl
<< std::endl;
std::cout << "\tReference Information: " << std::endl;
std::cout
<< "\t\tref_to_score Address:\t"
<< &ref_to_score
<< std::endl
<< "\t\tref_to_score value:\t\t"
<< ref_to_score
<< std::endl
<< "\t\tref_to_score& Size:\t\t"
<< sizeof(ref_to_score)
<< std::endl
<< std::endl;
std::cout << "# After Modifying with original: ------------------------------------" << std::endl << std::endl;
std::cout << "\tOriginal Variable Information: " << std::endl;
// Modifying the references will affect on the original variable and vice versa
score = 1234567;
// After Modifying
std::cout
<< "\t\tscore Address:\t\t\t"
<< &score
<< std::endl
<< "\t\tscore value:\t\t\t"
<< score
<< std::endl
<< "\t\tscore Size:\t\t\t\t"
<< sizeof(score)
<< std::endl
<< std::endl;
std::cout << "\tReference Information: " << std::endl;
std::cout
<< "\t\tref_to_score Address:\t"
<< &ref_to_score
<< std::endl
<< "\t\tref_to_score value:\t\t"
<< ref_to_score
<< std::endl
<< "\t\tref_to_score& Size:\t\t"
<< sizeof(ref_to_score)
<< std::endl
<< std::endl;
std::cout << std::endl;
std::cout << std::endl;
}
#endif