Initialization¶
1 2 3 4 5 6 7 8 |
|
Assignment style:
- Confusion with assignment (can be different for user defined types)
1 2 |
|
Constructor-call style ()
- Confusion with function declaration
- Not possible for class members in the definition of a class
Universal initialization - with {}
-
Can bee used (almost) everywhere
-
Warns about narrowing
-
Generalizes the notation used for initialization of arrays and structs in C
-
Can aso be used for passing parameters to constructors
-
Although sometimes with some abiguities, forcing the use of old-style initialization!
-
c++ std::vector<int> v(10, 2); // Create a vector with 10 elements all initialized to 2. std::vector<int> v{10, 2}; // Create a vector with two elements: 10 and 2.
-
This happens when there is a constructor of a class with a parameter of a special STL type
std::initializer_list<T>
. When writing your classes, consider avoiding such constructors. -
{}
results in default initialization, also fo the built-in types
Auto¶
-
auto
- the compiler infers the type&&) -
Can be decorated with
const
and&(&&)
or*
-
Good idea to use if often (AAA rule = Almost Always Auto)
- Forces to initialize
- Makes code more general and easier to refactor
- Avoids subtle errors and perfomance penalties (unexpected temporaries)
-
Helps when the type is known only to the compiler (e.g. lambdas)
-
Have to be careful to avoid pitfalls (related to type inference or assuming too much about the type)
1 2 3 4 5 6 7 8 9 10 |
|
Lambdas¶
1 2 3 4 5 6 7 8 |
|
Consists of
- Capture list
[...]
- the lambda introducer []
: captures nothing (as for regular functions)[&]
: all local names can be used (accessed by reference)[=]
: all local names can be used (their const copies are available)-
[capture-list]
specific captured names are given -
Formal parameter list (optional)
(parameters)
- Return type declaration (optional)
-> Type
- If not given, deduced the same way as for auto
- Body as for any other function
{...}
Lambdas are often used as arguments of STL (or your...) generic algorithms
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Class Basics¶
- In C++, class design can be emphasized by seperating class definition (in .h) from member definition (in .cpp)
- But not neccesarily for all member functions (and not at all for template classes)
Class definition
- Public part:
- Constructors
- Copy/Move constructors
- Member functions (including operator overloads)
- Destructor
- Private part:
- Data members
- Helper functions
Examples
Constructors¶
- Constructors in C++ are in many ways similar to constructors in C# and Java
1 2 3 4 |
|
- Initialization of class data members with member initializers
- Special syntax for initialization of data members and bases (super class parts)
- Emphasizing uniform use of
{}
notation - Place between the constructor header and body
- Initializes the data members from the formal parameters of the constructor
- If constructor(s) with parameters are given, no default constructor is generated!
- Constructor chaining (example rectangle class)
Destructors¶
- Destructors are essential for resource management
- Usually called implicitly:
- When an automatic (local) variable of class type goes out of scope
- Because of normal termination
- Because of exceptional termination: stack unwinding
- When a dynamically allocated object is explicitly deleted from the free store (the heap)
- With
delete
ordelete[]
- With
- Example: Alternative Point Class
Move Semantics¶
Rvalues¶
- An rvalue is an expression that is not an lvalue - an expression whose value does not have an identifiable (with a name!) position in memory, such as a temporary object
- Expressions that can appear at the right side of the assignment
- It does not make sense to take the address of an rvalue expression
1 2 3 4 5 6 7 8 9 10 11 12 |
|
References¶
- An rvalue reference is a reference to a tepmporary object (soon to dissapear) from which we can steal som constituents in order to avoid an expensive copy operation
- Binds to an rvalue, such as the returned value of many functions
- Used for "destructive read" that would otherwise have required a copy
- We want to overload some functions on Rvalue references in order to avoid expensive copy operations
- Intimately connected to move constructors
1 2 3 4 |
|
Copying vs Moving Constructors¶
- Moving
- Giving away details of an object instead of copying the dtails - "destructive read"
- object is left in undefined (but valid!) state
- For example, it should be possible to assign to it (if the
operator=
is defined)
- A move constructor
C(C&& a)
movesa
into the current object - A move constructor does not allocate resources - and should not throw any exception
- In contrast to a copy constructor
- If moving should take place, and if no move constructor exist, use the copy constructor (and pay the price)
A Class with Everything¶
1 2 3 4 5 6 7 8 9 10 11 |
|
Forcing the Move Semantics¶
- A "function"
std::move
can be used to convert into an rvalue type, thus causing the move semantics
1 2 3 4 5 6 |
|
Passing Arguments: Summary¶
- Ignoring pointers, the possible agreements between the caller and the function regarding an argumentz
- "Get a copy and do whatever you want with it"
- Pass by value:
void fun(MyClass x);
- "Work on it and give me back"
- Pass by lvalue reference:
void fun(MyClass& x);
- "Just look at it, no touching"
- Pass by const lvalue reference:
void fun(const MyClass& x);
-
Note: the function may end up working on a temporary copy (if some type conversion had to be done)!
-
"Use it, but give me back a box"
- Pass by rvalue reference:
void fun(MyClass&& x);