lifetime and references
object
sizeof(name)
alignof(name)
.................
decltype(name)
name
#name
.................
size
aligment
storage class
type
value
name
lifetime
(different than typeid(name))
(optional)
(may be undefined)
Scope
Scope (Name Validity)
Declaration point
Scope end
Scope
Block scope
Function scope
Function parameter scope
Namespace scope
Class scope
Enumeration scope
Template parameter scope
void f()
{
{
int x;
int y;
}
}
(labels only)
void f(int n)
{
}
namespace ns {
void f();
namespace {
void g();
}
inline namespace sub {
void h();
}
}
namespace ns {
}
(global namespace / global scope)
name lookup
int n;
void f(int n)
{
if (n > 5)
{
int n = 3;
n = 5;
}
}
#include <iostream>
void print(int n)
{
std::cout << n << std::endl;
}
Unqualified name lookup
Qualified name lookup
name lookup
Qualified
UN
{
{
{
{
x = 3;
}
}
}
}
namespace ns
{
struct X{};
void f(X);
}
void f()
{
ns::X x;
f(x);
}
name lookup
Qualified
UN
Argument dependent lookup (ADL)
name lookup
Qualified
namespace n1
{
namespace n2::n3
{
namespace n4
{
namespace
{
inline namespace n
{
void f();
}
}
}
}
}
::n1::n2::n3::n4::f();
name lookup
Qualified
object
lifetime
Scope
name
pointers
(addresses)
Prototype
Address operator
Dereference operator
Member access operator
Type*
&object
*pointer
pointer->member
struct type
{
int member1;
bool member2;
}
type object = {1, true};
type* obj_ptr = &object;
(*obj_ptr) = {0, false};
obj_ptr->member12 = true;
pointers
dangling
int* f()
{
int x = 5;
return &x;
}
void g()
{
int* ptr = f();
z = *ptr; // UB
}
int x = 2;
int* x_ptr = &x;
(*x_ptr) = 5;
int y = 5;
x_ptr = &y;
x_ptr = nullptr;
int x = 2;
int& x_ref = x;
x_ref = 5;
int y;
x_ref = y; // x == y cannot rebind
// no 'null reference'
pointers
references
Taking parameters by value or by reference
1.
value
reference
void foo(int x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
2.
void foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
Taking parameters by value or by reference
1.
value
reference
void foo(int x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 3
}
2.
int foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
Taking parameters by value or by reference
value
reference
2.
void foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
1.
void foo(int x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 3
}
int foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
Taking parameters by value or by reference
value
reference
2.
void foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 4
}
1.
void foo(int x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 3
}
int foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
Taking parameters by value or by reference
value
reference
2.
void foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 4
}
1.
void foo(int x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
// m == 3
}
int foo(int& x)
{
++x;
}
int main()
{
int n = 3;
foo(3);
int m = n;
}
1.1.
void foo(int a[])
{
a[0] = 1;
}
int main()
{
int a[1] = {3};
foo(a);
int m = a[0];
// m == 1
}
HOW TO Take constants as parameters?
Constants
parameters
#include <iostream>
int countChars(char str[], int length, char c) {
int result = 0;
for (int i = 0; i < length; ++i) {
if (str[i] == c) {
++result;
}
}
return result;
}
int main() {
std::cout << countChars("Hello World", 11, 'e');
}
HOW TO Take constants as parameters?
Constants
parameters
#include <iostream>
int countChars(char* str, int length, char c) {
int result = 0;
for (int i = 0; i < length; ++i) {
if (str[i] == c) {
++result;
}
}
return result;
}
int main() {
std::cout << countChars("Hello World", 11, 'e');
}
HOW TO Take constants as parameters?
Constants
parameters
Const
const int x = 4;
x = 3; // error
int*
int* const
const int*
const int* const
const pointers
int&
const int&
const references
HOW TO Take constants as parameters?
Constants
parameters
#include <iostream>
int countChars(const char* str, int length, char c) {
int result = 0;
for (int i = 0; i < length; ++i) {
if (str[i] == c) {
++result;
}
}
return result;
}
int main() {
std::cout << countChars("Hello World", 11, 'e');
}
HOW TO Take strings as parameters?
strings
parameters
#include <iostream>
#include <string_view> // C++17
int countChars(const std::string_view s, char c) {
int result = 0;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == c) {
++result;
}
}
return result;
}
int main() {
std::cout << countChars("Hello World", 'e');
}
references
r-value references ( )
l-value references ( )
forwarding references ( )
Type&
Type&&
Type&&
int x = 3,
y = 8;
std::string s = "Hello"
std::string s2 = std::to_string(x);
int z = x + y;
references
r-value
Temporary lifetime extension
Function overload selection
std::string s = "Hello";
//std::string& s_ref = s + " World";
std::string&& s_rref = s + " World";
s_rref += "!\n";
void std::string f(const std::string&);
void std::string f(std::string&&);
std::string s = "Hello";
f(s);
f(s + " World!\n");
- move constructors
- move assignment operators
- move aware functions
-
std::vector::push_back
-
lifetime and references
Lifetime and References
By Jan Bielak
Lifetime and References
A presentation about the lifetime and references in C++. It is presented here: https://www.youtube.com/watch?v=3TG_hnd3qqg .
- 580