SlideShare una empresa de Scribd logo
1 de 21
Descargar para leer sin conexión
1
Nico Ludwig (@ersatzteilchen)
(5) C++ Abstractions
2
TOC
● (5) C++ Abstractions
– The Copy-Operator=
– The "Rule of Three"
– Lvalues and C++11 Rvalues
– (C++11: The "Rule of Five")
– Equality Operators
– Comparison Operators and Equivalence
– Non-Member Function Operators and Friends
– The Output Operator
● Sources:
– Bjarne Stroustrup, The C++ Programming Language
– John Lakos, Large-Scale C++ Software Design
3
The Problem with shared Data – Copy Assignment
● Let's revisit the type Person, which handles dynamic data.
– Assigning a Person-object to another Person leads to undefined behavior in one dtor!
● The automatically created copy-operator= just copies all fields, not the referenced memory.
– I.e. the copy-operator= of the UDT calls the copy-operator= for each field.
– It results in Person-copies having copied pointers to the same location in memory (name).
– Every Person-copy will try to delete (dtor) the same location in memory via its pointer-copy.
class Person { // (members hidden)
char* name;
public:
Person(const char* name) {
if (name) {
this->name = new char[std::strlen(name) + 1];
std::strcpy(this->name, name);
}
}
~Person() {
delete[] this->name;
}
};
{
Person nico("nico");
Person alfred("alfred");
nico = alfred; // operator= creates a copy.
} // Undefined behavior: crash!
{
// Virtually following is executed:
nico.name = alfred.name;
// … for each field in Person!
}
4
The automatically created Copy-Operator=
● When alfred is assigned to nico:
– The automatically generated copy-operator= does only assign alfred's fields (i.e. name).
– operator= doesn't manage the occupied memory in depth, it's a shallow assignment.
– The automatically generated copy-operator= is public, also for classes!
● We have two Persons, both pointing to the same location in the freestore.
– The memory referenced by nico.name before the assignment is lost, leading to a memory leak.
– This leads to two Persons feeling responsible for name's memory.
– => In effect the same memory will be freed twice!
– We hurt fundamental rules when dealing with dynamic memory!
class Person { // (members hidden)
char* name;
};
{
Person nico("nico");
Person alfred("alfred")
nico
nico.name0x00076f2c
0'c' 'o''i''n'
alfred
alfred.name0x0007ff45
nico = alfred;
nico's dtoralfred's dtor
0'e' 'd''r''f''l''a'
}
0x0007ff45
0'c' 'o''i''n' :-(
0'e' 'd''r''f''l''a' :-(
5
Implementation of Copy-Operator= – A first Look
● The solution: overload the operator= with correct copy semantics.
● We've to overload operator= to make a deep copy of the original to care for "stale" memory and to avoid memory leaks.
class Person { // (members hidden)
public:
Person(const char* name) {
/* pass */
}
// The overloaded operator=.
Person& operator=(const Person& rhs) {
if (this != &rhs) { // Self-assignment guard.
delete[] this->name;
this->name = new char[std::strlen(rhs.name) + 1];
std::strcpy(this->name, rhs.name);
}
return *this;
}
~Person() {
delete[] this->name;
}
};
{
Person nico("nico");
Person alfred("alfred");
nico = alfred;
} // Fine!
{
// Virtually following is executed:
nico.operator=(alfred);
}
● C++ is a language, in which the operator-support is
based on functions. And here we're about to
overload just these functions.
6
Implementation of Copy-Operator= in Detail
● A correct implementation of copy-operator= should:
– Accept a (preferably const) reference of the type to be assigned.
●
The parameter carries the object right from the assignment (rhs: "right hand side")
● The parameter should be a const&, because we don't want to modify the rhs!
– Check the parameter against this (identity), so that no self-assignment can happen!
● It could lead to freeing the memory in (1) that we want to copy in (2).
●
In short, this syntax should work:
– Free the assigned-to memory (1) and copy the assigning memory (2).
– return a reference to this (Then no copy is created!), to make this syntax work:
Person& Person::operator=(const Person& rhs) {
if (this != &rhs) { // rhs is not identical to this.
delete[] this->name; // (1)
this->name = new char[std::strlen(rhs.name) + 1]; // (2)
std::strcpy(this->name, rhs.name); // (2) continued
}
return *this;
}
Person joe("joe");
nico = alfred = joe; // Multiple assignment.
nico = nico; // Self-assignment.
● An alternative to the shown implementation of the
cctor and the copy assignment is to use the "copy
and swap idiom".
● If an operator returns an object of same type, on
which it was called, the operator (or in mathematical
terms "the operation") is said to be "closed on that
type".
7
The "Rule of Three"
● The automatically generated dtor, cctor and copy-operator= are often useless:
– If a UDT should behave like a fundamental type and
– if a UDT should follow value semantics (i.e. copy semantics).
– And they are public also for classes!
● Therefor the "Rule of Three" claims that a UDT defining any of these "operators":
– dtor,
– cctor or
– copy-operator=
– should define all of them!
● The "Rule of Three" completes our idea of RAII.
– Dtor, cctor and copy-operator= are often called "The big Three".
● A UDT obeying the "Rule of Three" is often said to be in the "canonical form".
C++11 – explicit defaulting/deleting of special member functions
class NCPerson { // A non-copyable UDT Person.
public:
NCPerson() = default;
NCPerson(const NCPerson&) = delete;
NCPerson & operator=(const NCPerson&) = delete;
};
● Operators can be overloaded in order to mimic
fundamental types, therefor ctors (esp. dctors and
cctors), and dtors are also operators!
8
C++11: static Analysis of Type Traits
● C++11 provides means to analyze types during compile time.
– These means where introduced to allow advanced and robust C++ meta programming.
– But it can also be used learn something about C++ types.
● Meta programming is the "if-then-else of types".
C++11 – type traits
cout<<std::boolalpha<<std::is_copy_assignable<Person>()<<std::endl;
// >true
// Selection of type traits available in C++11:
std::is_array, std::is_class, std::is_copy_assignable, std::is_copy_constructible, std::is_enum,
std::is_floating_point, std::is_function, std::is_integral, std::is_lvalue_reference,
std::is_member_function_pointer, std::is_member_object_pointer, std::is_pointer,
std::is_rvalue_reference, std::is_union, std::is_void, std::is_arithmetic, std::is_compound,
std::is_fundamental, std::is_member_pointer, std::is_object, std::is_reference, std::is_scalar,
std::is_abstract, std::is_const, std::is_empty, std::is_literal_type, std::is_pod, std::is_polymorphic,
std::is_signed, std::is_standard_layout, std::is_trivial, std::is_trivially_copyable,
std::is_unsigned, std::is_volatile
9
When is no "Rule of Three" required to be implemented?
● If the "Big Three" are not explicitly coded, they'll be generated by the compiler:
– The cctor, copy-operator= and the dtor of all the fields in the UDT will be called.
– So, if all fields implement the "Big Three", nothing is to do in the UDT.
● Assume following UDT MarriedCouple:
– The fields are of type Person.
– The used UDT Person implements the "Big Three" and RAII.
– MarriedCouple delegates its "Big Three" activities to its Person fields.
– => No special member functions need to be implemented in MarriedCouple!
class MarriedCouple {
Person spouse1;
Person spouse2;
public:
MarriedCouple(const Person& spouse1, const Person& spouse2)
: spouse1(spouse1), spouse2(spouse2) {}
};
● If std::string was used in Person instead of char*,
the "Big Three" wouldn't need to be implemented
explicitly.
10
Lvalues and C++11 Rvalues
● Up to now we've dealt with two sorts of values:
– Lvalues: "allowed left from assignment", have an address, controlled by programmers.
– Non-lvalues: literals and temporarily created values (temps), have no known address.
● Non-lvalues can only be accepted by non-references andconst&.
– The problem: either is a (deep) copy created or a non-modifiable object (const&).
● C++11 closes the gap between lvalues and non-lvalues with rvalues.
– Rvalues: modifiable references to non-lvalues controlled by compilers.
– Rvalues allow binding non-lvalues to modifiable referencesimplementing move semantics.
– With move semantics literals and temps need not to be copied, but can be modified.
– In C++11 we can control move-semantics additionally to copy-semantics.
– Rvalues enable another new feature in C++: perfect forwarding.
● In C++11 the "Rule of Three" can be extended to the "Rule of Five" with move-semantics.
C++11 – rvalue declarator
void AcceptsPerson(Person&& person);
11
C++11: Move Semantics
● In C++ there are situations, in which deep copies are not really required.
● Neither the object Person("joe") nor Person("dave") is required after creation.
– Their values are just stored in the variable nico and AcceptsPerson()'s parameter respectively.
– And then the rvalues Person("joe") and Person("dave") cease to exist.
● The idea is that the memory from the rvalues can be stolen instead of copied.
– This is what we call move-semantics instead of copy-semantics.
– In C++11 we can write code handling move construction (1) and move assignment (2).
AcceptsPerson(Person("dave")); // (1) Move constructor
nico = Person("joe"); // (2) Move assignment
C++11 – move constructor
Person::Person(Person&& original)
: name(original.name) /* Stealing! */ {
original.name = nullptr; // Ok on rvalue!
} /* or: */
// Implementation that forwards to move assignment:
Person(Person&& original) {
*this = std::move(original); // Declared in <utility>.
}
C++11 – move assignment operator
Person& Person::operator=(Person&& rhs) {
if (this != &rhs) {
delete [] this->name;
this->name = rhs.name; // Stealing!
rhs.name = nullptr; // Ok on rvalue!
}
return *this;
}
● By default, most C++ compilers are able to optimize
code in a way, so that this kind of superfluous
copying is removed. The optimization of mtor and
move assignment needs to be deactivated to make
the explicitly implemented operators visible (gcc-
option: -fno-elide-constructors).
● The function std::move() just converts its argument
to a type to reach the correct overload for rvalues.
12
Essential Operators: Operator== and Operator!= – Part I
● What is equality? When do we understand objects to be equal?
– Considering nico1 and nico2 as equal, we assume their fields have the same content.
– Alas the operator== can't be used on Persons, because this operator isn't defined yet.
● What is identity?
– The identity of objects can be specifically answered for C/C++...
– ...objects having the same address are identical. Those objects share the same location in memory.
– Identity-comparison is intrinsic in C/C++ as pointers are directly supported. It is also called referential equality.
– (We already checked for identity to avoid self-assignment)
● Equality: objects have the same content. It is also called structural equality.
– Once again in opposite to identity, where objects just have the same address.
Person nico1("nico");
Person nico2("nico");
bool equalPersons = nico1 == nico2; // Won't compile for now!
bool identicalPersons = &nico1 == &nico2; // Will almost always compile!
if (this != &rhs) … // Self-assignment guard.
● What are the results in equalPersons and
identicalPersons?
13
Essential Operators: Operator== and Operator!= – Part II
● Good, let's implement operator==:
● And operator!= in terms of operator==:
● The signature of the equality operators shouldn't be a surprise:
– Both are binary operators, the member functions accept the rhs and this is the "lhs".
– They return a bool result and should be declared const.
bool Person::operator==(const Person& rhs) const {
if (this != &rhs) { // If rhs is not identical to this, compare the fields:
return 0 == std::strcmp(this->name, rhs.name);
}
return true; // Self-comparison, both objects are identical: always true!
}
bool Person::operator!=(const Person& rhs) const {
return !this->operator==(rhs); // Just negate operator==.
}
class Person { // (members hidden)
public:
bool operator==(const Person& rhs) const;
bool operator!=(const Person& rhs) const;
};
14
Free Operators
● C++ allows operators to be overloaded as
– member functions
– or as free functions.
– Mind that we can only access public members (GetName()) in the free operator==!
● Some operators can only be overloaded as member functions:
– type conversion, operator=, operator(), operator[] and operator->.
bool operator==(const Person& lhs, const Person& rhs) { // Free function.
if (&lhs != &rhs) { // If lhs is not identical to rhs, compare the fields:
return 0 == std::strcmp(lhs.GetName(), rhs.GetName());
}
return true; // Self-comparison, both objects are identical: always true!
}
bool Person::operator==(const Person& rhs) const { // Member function
if (this != &rhs) { // If rhs is not identical to this, compare the fields:
return 0 == std::strcmp(this->name, rhs.name);
}
return true; // Self-comparison, both objects are identical: always true!
}
15
Overload an Operator as free or Member Function?
● Often it depends on whether implicit conversion of the lhs is desired.
– E.g. with having Person's operator== as member function we'll have an asymmetry:
● (2) An implicit conversion from const char* to Person works, but conversion of the lhs "nico" to "this" won't work!
●
(3) It works as the rhs const char* will be implicitly converted into Person. (2)/(3) are asymmetric!
●
(4) Just performs a pointer comparison; operators for fundamental types can't be "overridden".
● (The compiler needed the free operator==(const char*, const Person&) to be present additionally.)
– Then with having Person's operator== as only one free function symmetry works:
● The implicit conversion makes (2) and (3) work symmetrically! (4) still doesn't call "our" operator==!
Person nico("nico");
Person dave("dave");
bool result = nico == dave; // (1) Ok! Should be clear.
bool result2 = "nico" == nico; // (2) Invalid!
bool result3 = nico == "nico"; // (3) Ok!
bool result4 = "nico" == "nico"; // (4) Oops! Compares two const char*!
Person nico("nico");
Person dave("dave");
bool result = nico == dave; // (1) Ok! Should be clear.
bool result2 = "nico" == nico; // (2) Ok!
bool result3 = nico == "nico"; // (3) Ok!
bool result4 = "nico" == "nico"; // (4) Oops! Compares two const char*!
bool Person::operator==(const Person& rhs) const {
/* pass */
}
bool operator==(const Person& lhs, const Person& rhs) {
/* pass */
}
16
Friends
● Free functions and operator overloads can be granted access to private members.
– This can be done by declaring them as friends of the UDT in the defining UDT:
– With granted friendship, the free operator== can access Person's private members:
● When to use friends:
– If access to "non-publicised" members is required.
– If extra performance is awaited by accessing private members (often fields) directly.
– Rule: avoid using friends! They're potentially dangerous as they break encapsulation.
// Free function as friend of Person:
bool operator==(const Person& lhs, const Person& rhs) {
return (&lhs != &rhs)
? 0 == std::strcmp(lhs.name, rhs.name) // private field name
: true;
}
class Person { // (members hidden)
// The friendship declares that a free function with this signature
// will get access to all members (incl. private members) of
// Person. !!This is no declaration of a member function!!
friend bool operator==(const Person& lhs, const Person& rhs);
};
17
Essential Operators: Operator< and Equivalence
● The implementation of the operator< for Person shouldn't be a surprise:
● The relational comparison operator< is very important in C++!
– It can be used to implement all other relational comparison operators:
– Esp. the C++ Standard Template Library (STL) exploits the operator< like this.
●
E.g. the STL uses the operator< to implement sorting of elements!
● Expressing operator== in terms of operator< is called equivalence comparison.
– Equivalence defines equality in terms of the element-order in an ordered sequence.
– The term "equivalence" is taken from maths: see "equivalence relations".
bool operator<(const Person& lhs, const Person& rhs) {
return (&lhs != &rhs) ? 0 > std::strcmp(lhs.name, rhs.name) : false;
}
Person nico("nico"), dave("dave");
bool result = nico < dave;
// >false
bool operator>(const Person& lhs, const Person& rhs) { return rhs < lhs; }
bool operator==(const Person& lhs, const Person& rhs) { return !(lhs < rhs) && !(rhs < lhs); }
bool operator!=(const Person& lhs, const Person& rhs) { return (lhs < rhs) || (rhs < lhs); }
bool operator>=(const Person& lhs, const Person& rhs) { return !(lhs < rhs); }
bool operator<=(const Person& lhs, const Person& rhs) { return !(rhs < lhs); }
● This example shows all the equivalence operators
available in C++. It's important to understand that
these operators mustn't be overridden with pointer
parameters. This is because we are not allowed to
define binary operators only accepting pointers, as
this would override the basic equivalence operators
the language defines for pointers. It's also
questionable (but allowed) to override binary
operators in a way that only one of the parameters
is a pointer type. - This would lead to a strange
syntax that was not awaited by other developers.
● In C++ it is not required to overload all the relational
operators separately as shown here. If only the
operators < and == are defined for a type, based on
this operator the other relational operators can be
synthesized by the language. → Just include the h-
file <utility> and add a using directive for the
namespace std::rel_ops.
18
Essential Operators: Operator<<
● The operator<< is a binary operator, originally expressing left bit shift.
– Traditionally it's overloaded to express "sending an object to an output stream" in C++.
●
E.g. can we send an object to the standard output-stream std::cout with its operator<<.
– We can overload operator<< in "our" UDTs to exploit using streams for "our" UDTs.
● Overloading operator<< as member works, but the order of arguments is odd.
● Let's fix this and discuss this operator's signature.
Person nico("nico");
std::cout<<nico; // Invalid! A Person object needs to be the lhs!
nico<<std::cout; // Oops! Person's operator<< can't be used
// >nico // similar to fundamental types!
class Person { // (members hidden)
public:
std::ostream& operator<<(std::ostream& out) const {
return out<<GetName();
}
};
19
Essential Operators: Operator<< – the correct Way
● In fact, the lhs of this operator<< needs to of type std::ostream; it can't be coded as member function!
– Mind that in a member function the lhs would be this!
● So we've another reason to choose a free operator overload: order of arguments!
● The signature and implementation of operator<< for stream output of a UDT:
– It accepts a non-const& to std::ostream as lhs (out) and a const& of the UDT as rhs.
●
The lhs is a non-const& because it is modified! The operator<< sends to, or writes to out!
● As the lhs is of type std::ostream, it accepts std::cout as well std::ofstreams (substitution principle).
– The implementation just calls operator<< on the passed std::ostream for its fields (1).
– It returns the passed std::ostream& to allow chaining syntax (2)!
Person nico("nico");
Person dave("dave");
// Ok! rhs as a Person object!
std::cout<<nico;
// (2) Chaining syntax:
std::cout<<" "<<dave<<" : "<<nico<<std::endl;
// >dave : nico
std::ostream& operator<<(std::ostream& out, const Person& rhs) {
return out<<rhs.GetName(); // (1)
}
20
Operator Overloading – Tips
● Generally don't overload non-essential operators to have "aesthetic" code!
– (Well, it's cool, because we kind of extend C++ by overloading present operators!)
– In essence it only makes sense, if we define numeric types!
● And the definition of numeric UDTs is not an every day's job.
●
Often it's an interesting school-exercise, but it's rarely done in the wild.
– It's often done downright wrong – w/o analogy to fundamental types!
●
A little sneakier syntax isn't worth confusing consumers (arcane, not aesthetic) of such UDTs.
● Tips:
– Operators modifying this/lhs should return a non-const& to this/lhs to allow chaining.
– Some binary operators create and return a new instance of the UDT, no reference.
– Keep operator and compound assignment (e.g. + and +=) consistent.
● C++ won't infer compound assignment for us.
– Never overload &&, || and , (comma/sequence operator) in C++!
– Sometimes overloads of the operators++/--/</== are required for the STL to work.
– Use free function operator overloads to exploit order of arguments or type conversion.
● The operators =, & and , (and the dctor and non-
virtual dtor) have predefined meanings.
21
Thank you!

Más contenido relacionado

La actualidad más candente

Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 
Let's talk about jni
Let's talk about jniLet's talk about jni
Let's talk about jniYongqiang Li
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for DummiesElizabeth Smith
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 pramode_ce
 
Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22nikomatsakis
 
Smart Pointer in C++
Smart Pointer in C++Smart Pointer in C++
Smart Pointer in C++永泉 韩
 
Scala design pattern
Scala design patternScala design pattern
Scala design patternKenji Yoshida
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performanceDuoyi Wu
 
Memory management in C++
Memory management in C++Memory management in C++
Memory management in C++Ilio Catallo
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorialnikomatsakis
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 Sumant Tambe
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)allanh0526
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrencyAlex Navis
 
Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!Kel Cecil
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 

La actualidad más candente (20)

Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
Groovy closures
Groovy closuresGroovy closures
Groovy closures
 
How to write Ruby extensions with Crystal
How to write Ruby extensions with CrystalHow to write Ruby extensions with Crystal
How to write Ruby extensions with Crystal
 
Let's talk about jni
Let's talk about jniLet's talk about jni
Let's talk about jni
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017
 
Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22
 
Smart Pointer in C++
Smart Pointer in C++Smart Pointer in C++
Smart Pointer in C++
 
Scala design pattern
Scala design patternScala design pattern
Scala design pattern
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performance
 
Memory management in C++
Memory management in C++Memory management in C++
Memory management in C++
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorial
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
 
Lazy java
Lazy javaLazy java
Lazy java
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!
 
C++ Advanced Features
C++ Advanced FeaturesC++ Advanced Features
C++ Advanced Features
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
C++ Advanced Features
C++ Advanced FeaturesC++ Advanced Features
C++ Advanced Features
 

Destacado

Uuganjargal tsahim 2
Uuganjargal tsahim 2Uuganjargal tsahim 2
Uuganjargal tsahim 2Nergui85
 
Optional Parameters
Optional ParametersOptional Parameters
Optional ParametersRobPaulson
 
Barcelona Abans
Barcelona AbansBarcelona Abans
Barcelona Abanscandiamir
 
Careers Link To Bureau Of Labor
Careers Link To Bureau Of LaborCareers Link To Bureau Of Labor
Careers Link To Bureau Of Laborpajaration07
 
Mensajería SMS en el Sector Público
Mensajería SMS en el Sector PúblicoMensajería SMS en el Sector Público
Mensajería SMS en el Sector PúblicoOriol Ros i Mas
 
Review of don’t ask, don’t tell challenges in delivering qualitative find...
Review  of  don’t ask, don’t tell   challenges in delivering qualitative find...Review  of  don’t ask, don’t tell   challenges in delivering qualitative find...
Review of don’t ask, don’t tell challenges in delivering qualitative find...Merlien Institute
 
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013Awara Direct Search
 
Welcome to 247 home rescue
Welcome to 247 home rescueWelcome to 247 home rescue
Welcome to 247 home rescueKevin Burke SEO
 
ArtíCulos Atrasados
ArtíCulos AtrasadosArtíCulos Atrasados
ArtíCulos Atrasadospacoayal
 
תקנות סדא הצעת הרפורמה המלאה
תקנות סדא הצעת הרפורמה המלאהתקנות סדא הצעת הרפורמה המלאה
תקנות סדא הצעת הרפורמה המלאהthemarkertlv
 
Bando Concorso Allievi Marescialli Carabinieri 2014
Bando Concorso Allievi Marescialli Carabinieri 2014 Bando Concorso Allievi Marescialli Carabinieri 2014
Bando Concorso Allievi Marescialli Carabinieri 2014 Concorsando.it
 
02 multimedia andinteractivity
02 multimedia andinteractivity02 multimedia andinteractivity
02 multimedia andinteractivityMultimedia System
 
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...dawnnicolene
 
Twinny Cra Peñas Spain - 2nd Week
Twinny Cra Peñas Spain - 2nd WeekTwinny Cra Peñas Spain - 2nd Week
Twinny Cra Peñas Spain - 2nd Weekcrapsp
 

Destacado (20)

Uuganjargal tsahim 2
Uuganjargal tsahim 2Uuganjargal tsahim 2
Uuganjargal tsahim 2
 
Optional Parameters
Optional ParametersOptional Parameters
Optional Parameters
 
Barcelona Abans
Barcelona AbansBarcelona Abans
Barcelona Abans
 
Careers Link To Bureau Of Labor
Careers Link To Bureau Of LaborCareers Link To Bureau Of Labor
Careers Link To Bureau Of Labor
 
Schools insurance key_facts
Schools insurance key_factsSchools insurance key_facts
Schools insurance key_facts
 
Hanoi
HanoiHanoi
Hanoi
 
Mensajería SMS en el Sector Público
Mensajería SMS en el Sector PúblicoMensajería SMS en el Sector Público
Mensajería SMS en el Sector Público
 
Punto de partida
Punto de partidaPunto de partida
Punto de partida
 
Review of don’t ask, don’t tell challenges in delivering qualitative find...
Review  of  don’t ask, don’t tell   challenges in delivering qualitative find...Review  of  don’t ask, don’t tell   challenges in delivering qualitative find...
Review of don’t ask, don’t tell challenges in delivering qualitative find...
 
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013
Kane Tuohy. Financial and Commercial Center Ireland 07.06.2013
 
Welcome to 247 home rescue
Welcome to 247 home rescueWelcome to 247 home rescue
Welcome to 247 home rescue
 
Coloquio de tecnologia
Coloquio de tecnologiaColoquio de tecnologia
Coloquio de tecnologia
 
ArtíCulos Atrasados
ArtíCulos AtrasadosArtíCulos Atrasados
ArtíCulos Atrasados
 
תקנות סדא הצעת הרפורמה המלאה
תקנות סדא הצעת הרפורמה המלאהתקנות סדא הצעת הרפורמה המלאה
תקנות סדא הצעת הרפורמה המלאה
 
Bando Concorso Allievi Marescialli Carabinieri 2014
Bando Concorso Allievi Marescialli Carabinieri 2014 Bando Concorso Allievi Marescialli Carabinieri 2014
Bando Concorso Allievi Marescialli Carabinieri 2014
 
Cole verano model (1)
Cole verano model (1)Cole verano model (1)
Cole verano model (1)
 
02 multimedia andinteractivity
02 multimedia andinteractivity02 multimedia andinteractivity
02 multimedia andinteractivity
 
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...
Blogspot: NORTON SCIENTIFIC SCAM-Detection and Prevention of Clinical Researc...
 
Twinny Cra Peñas Spain - 2nd Week
Twinny Cra Peñas Spain - 2nd WeekTwinny Cra Peñas Spain - 2nd Week
Twinny Cra Peñas Spain - 2nd Week
 
Storyboard
StoryboardStoryboard
Storyboard
 

Similar a (5) cpp abstractions essential_operators

(4) cpp abstractions references_copies_and_const-ness
(4) cpp abstractions references_copies_and_const-ness(4) cpp abstractions references_copies_and_const-ness
(4) cpp abstractions references_copies_and_const-nessNico Ludwig
 
A brief introduction to lisp language
A brief introduction to lisp languageA brief introduction to lisp language
A brief introduction to lisp languageDavid Gu
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
An Experiment with Checking the glibc Library
An Experiment with Checking the glibc LibraryAn Experiment with Checking the glibc Library
An Experiment with Checking the glibc LibraryAndrey Karpov
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyTypesafe
 
smart pointers are unique concept to avoid memory leakage
smart pointers are unique concept to avoid memory leakagesmart pointers are unique concept to avoid memory leakage
smart pointers are unique concept to avoid memory leakagedradeeljaved1
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndEdward Chen
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answersAkash Gawali
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
Tokyo APAC Groundbreakers tour - The Complete Java Developer
Tokyo APAC Groundbreakers tour - The Complete Java DeveloperTokyo APAC Groundbreakers tour - The Complete Java Developer
Tokyo APAC Groundbreakers tour - The Complete Java DeveloperConnor McDonald
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And AnswerJagan Mohan Bishoyi
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
02 functions, variables, basic input and output of c++
02   functions, variables, basic input and output of c++02   functions, variables, basic input and output of c++
02 functions, variables, basic input and output of c++Manzoor ALam
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial javaTpoint s
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
(7) c sharp introduction_advanvced_features_part_ii
(7) c sharp introduction_advanvced_features_part_ii(7) c sharp introduction_advanvced_features_part_ii
(7) c sharp introduction_advanvced_features_part_iiNico Ludwig
 

Similar a (5) cpp abstractions essential_operators (20)

(4) cpp abstractions references_copies_and_const-ness
(4) cpp abstractions references_copies_and_const-ness(4) cpp abstractions references_copies_and_const-ness
(4) cpp abstractions references_copies_and_const-ness
 
A brief introduction to lisp language
A brief introduction to lisp languageA brief introduction to lisp language
A brief introduction to lisp language
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
An Experiment with Checking the glibc Library
An Experiment with Checking the glibc LibraryAn Experiment with Checking the glibc Library
An Experiment with Checking the glibc Library
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin Odersky
 
What is c
What is cWhat is c
What is c
 
smart pointers are unique concept to avoid memory leakage
smart pointers are unique concept to avoid memory leakagesmart pointers are unique concept to avoid memory leakage
smart pointers are unique concept to avoid memory leakage
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 
Tokyo APAC Groundbreakers tour - The Complete Java Developer
Tokyo APAC Groundbreakers tour - The Complete Java DeveloperTokyo APAC Groundbreakers tour - The Complete Java Developer
Tokyo APAC Groundbreakers tour - The Complete Java Developer
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
02 functions, variables, basic input and output of c++
02   functions, variables, basic input and output of c++02   functions, variables, basic input and output of c++
02 functions, variables, basic input and output of c++
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
(7) c sharp introduction_advanvced_features_part_ii
(7) c sharp introduction_advanvced_features_part_ii(7) c sharp introduction_advanvced_features_part_ii
(7) c sharp introduction_advanvced_features_part_ii
 

Más de Nico Ludwig

Grundkurs fuer excel_part_v
Grundkurs fuer excel_part_vGrundkurs fuer excel_part_v
Grundkurs fuer excel_part_vNico Ludwig
 
Grundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivGrundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivNico Ludwig
 
Grundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiGrundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiNico Ludwig
 
Grundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiGrundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiNico Ludwig
 
Grundkurs fuer excel_part_i
Grundkurs fuer excel_part_iGrundkurs fuer excel_part_i
Grundkurs fuer excel_part_iNico Ludwig
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivityNico Ludwig
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivityNico Ludwig
 
New c sharp4_features_part_vi
New c sharp4_features_part_viNew c sharp4_features_part_vi
New c sharp4_features_part_viNico Ludwig
 
New c sharp4_features_part_v
New c sharp4_features_part_vNew c sharp4_features_part_v
New c sharp4_features_part_vNico Ludwig
 
New c sharp4_features_part_iv
New c sharp4_features_part_ivNew c sharp4_features_part_iv
New c sharp4_features_part_ivNico Ludwig
 
New c sharp4_features_part_iii
New c sharp4_features_part_iiiNew c sharp4_features_part_iii
New c sharp4_features_part_iiiNico Ludwig
 
New c sharp4_features_part_ii
New c sharp4_features_part_iiNew c sharp4_features_part_ii
New c sharp4_features_part_iiNico Ludwig
 
New c sharp4_features_part_i
New c sharp4_features_part_iNew c sharp4_features_part_i
New c sharp4_features_part_iNico Ludwig
 
New c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNew c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNico Ludwig
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNico Ludwig
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNico Ludwig
 
New c sharp3_features_(linq)_part_iii
New c sharp3_features_(linq)_part_iiiNew c sharp3_features_(linq)_part_iii
New c sharp3_features_(linq)_part_iiiNico Ludwig
 
New c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNew c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNico Ludwig
 

Más de Nico Ludwig (20)

Grundkurs fuer excel_part_v
Grundkurs fuer excel_part_vGrundkurs fuer excel_part_v
Grundkurs fuer excel_part_v
 
Grundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivGrundkurs fuer excel_part_iv
Grundkurs fuer excel_part_iv
 
Grundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiGrundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iii
 
Grundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiGrundkurs fuer excel_part_ii
Grundkurs fuer excel_part_ii
 
Grundkurs fuer excel_part_i
Grundkurs fuer excel_part_iGrundkurs fuer excel_part_i
Grundkurs fuer excel_part_i
 
(2) gui drawing
(2) gui drawing(2) gui drawing
(2) gui drawing
 
(2) gui drawing
(2) gui drawing(2) gui drawing
(2) gui drawing
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivity
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivity
 
New c sharp4_features_part_vi
New c sharp4_features_part_viNew c sharp4_features_part_vi
New c sharp4_features_part_vi
 
New c sharp4_features_part_v
New c sharp4_features_part_vNew c sharp4_features_part_v
New c sharp4_features_part_v
 
New c sharp4_features_part_iv
New c sharp4_features_part_ivNew c sharp4_features_part_iv
New c sharp4_features_part_iv
 
New c sharp4_features_part_iii
New c sharp4_features_part_iiiNew c sharp4_features_part_iii
New c sharp4_features_part_iii
 
New c sharp4_features_part_ii
New c sharp4_features_part_iiNew c sharp4_features_part_ii
New c sharp4_features_part_ii
 
New c sharp4_features_part_i
New c sharp4_features_part_iNew c sharp4_features_part_i
New c sharp4_features_part_i
 
New c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNew c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_v
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_iv
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_iv
 
New c sharp3_features_(linq)_part_iii
New c sharp3_features_(linq)_part_iiiNew c sharp3_features_(linq)_part_iii
New c sharp3_features_(linq)_part_iii
 
New c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNew c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_ii
 

Último

Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 

Último (20)

Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 

(5) cpp abstractions essential_operators

  • 2. 2 TOC ● (5) C++ Abstractions – The Copy-Operator= – The "Rule of Three" – Lvalues and C++11 Rvalues – (C++11: The "Rule of Five") – Equality Operators – Comparison Operators and Equivalence – Non-Member Function Operators and Friends – The Output Operator ● Sources: – Bjarne Stroustrup, The C++ Programming Language – John Lakos, Large-Scale C++ Software Design
  • 3. 3 The Problem with shared Data – Copy Assignment ● Let's revisit the type Person, which handles dynamic data. – Assigning a Person-object to another Person leads to undefined behavior in one dtor! ● The automatically created copy-operator= just copies all fields, not the referenced memory. – I.e. the copy-operator= of the UDT calls the copy-operator= for each field. – It results in Person-copies having copied pointers to the same location in memory (name). – Every Person-copy will try to delete (dtor) the same location in memory via its pointer-copy. class Person { // (members hidden) char* name; public: Person(const char* name) { if (name) { this->name = new char[std::strlen(name) + 1]; std::strcpy(this->name, name); } } ~Person() { delete[] this->name; } }; { Person nico("nico"); Person alfred("alfred"); nico = alfred; // operator= creates a copy. } // Undefined behavior: crash! { // Virtually following is executed: nico.name = alfred.name; // … for each field in Person! }
  • 4. 4 The automatically created Copy-Operator= ● When alfred is assigned to nico: – The automatically generated copy-operator= does only assign alfred's fields (i.e. name). – operator= doesn't manage the occupied memory in depth, it's a shallow assignment. – The automatically generated copy-operator= is public, also for classes! ● We have two Persons, both pointing to the same location in the freestore. – The memory referenced by nico.name before the assignment is lost, leading to a memory leak. – This leads to two Persons feeling responsible for name's memory. – => In effect the same memory will be freed twice! – We hurt fundamental rules when dealing with dynamic memory! class Person { // (members hidden) char* name; }; { Person nico("nico"); Person alfred("alfred") nico nico.name0x00076f2c 0'c' 'o''i''n' alfred alfred.name0x0007ff45 nico = alfred; nico's dtoralfred's dtor 0'e' 'd''r''f''l''a' } 0x0007ff45 0'c' 'o''i''n' :-( 0'e' 'd''r''f''l''a' :-(
  • 5. 5 Implementation of Copy-Operator= – A first Look ● The solution: overload the operator= with correct copy semantics. ● We've to overload operator= to make a deep copy of the original to care for "stale" memory and to avoid memory leaks. class Person { // (members hidden) public: Person(const char* name) { /* pass */ } // The overloaded operator=. Person& operator=(const Person& rhs) { if (this != &rhs) { // Self-assignment guard. delete[] this->name; this->name = new char[std::strlen(rhs.name) + 1]; std::strcpy(this->name, rhs.name); } return *this; } ~Person() { delete[] this->name; } }; { Person nico("nico"); Person alfred("alfred"); nico = alfred; } // Fine! { // Virtually following is executed: nico.operator=(alfred); } ● C++ is a language, in which the operator-support is based on functions. And here we're about to overload just these functions.
  • 6. 6 Implementation of Copy-Operator= in Detail ● A correct implementation of copy-operator= should: – Accept a (preferably const) reference of the type to be assigned. ● The parameter carries the object right from the assignment (rhs: "right hand side") ● The parameter should be a const&, because we don't want to modify the rhs! – Check the parameter against this (identity), so that no self-assignment can happen! ● It could lead to freeing the memory in (1) that we want to copy in (2). ● In short, this syntax should work: – Free the assigned-to memory (1) and copy the assigning memory (2). – return a reference to this (Then no copy is created!), to make this syntax work: Person& Person::operator=(const Person& rhs) { if (this != &rhs) { // rhs is not identical to this. delete[] this->name; // (1) this->name = new char[std::strlen(rhs.name) + 1]; // (2) std::strcpy(this->name, rhs.name); // (2) continued } return *this; } Person joe("joe"); nico = alfred = joe; // Multiple assignment. nico = nico; // Self-assignment. ● An alternative to the shown implementation of the cctor and the copy assignment is to use the "copy and swap idiom". ● If an operator returns an object of same type, on which it was called, the operator (or in mathematical terms "the operation") is said to be "closed on that type".
  • 7. 7 The "Rule of Three" ● The automatically generated dtor, cctor and copy-operator= are often useless: – If a UDT should behave like a fundamental type and – if a UDT should follow value semantics (i.e. copy semantics). – And they are public also for classes! ● Therefor the "Rule of Three" claims that a UDT defining any of these "operators": – dtor, – cctor or – copy-operator= – should define all of them! ● The "Rule of Three" completes our idea of RAII. – Dtor, cctor and copy-operator= are often called "The big Three". ● A UDT obeying the "Rule of Three" is often said to be in the "canonical form". C++11 – explicit defaulting/deleting of special member functions class NCPerson { // A non-copyable UDT Person. public: NCPerson() = default; NCPerson(const NCPerson&) = delete; NCPerson & operator=(const NCPerson&) = delete; }; ● Operators can be overloaded in order to mimic fundamental types, therefor ctors (esp. dctors and cctors), and dtors are also operators!
  • 8. 8 C++11: static Analysis of Type Traits ● C++11 provides means to analyze types during compile time. – These means where introduced to allow advanced and robust C++ meta programming. – But it can also be used learn something about C++ types. ● Meta programming is the "if-then-else of types". C++11 – type traits cout<<std::boolalpha<<std::is_copy_assignable<Person>()<<std::endl; // >true // Selection of type traits available in C++11: std::is_array, std::is_class, std::is_copy_assignable, std::is_copy_constructible, std::is_enum, std::is_floating_point, std::is_function, std::is_integral, std::is_lvalue_reference, std::is_member_function_pointer, std::is_member_object_pointer, std::is_pointer, std::is_rvalue_reference, std::is_union, std::is_void, std::is_arithmetic, std::is_compound, std::is_fundamental, std::is_member_pointer, std::is_object, std::is_reference, std::is_scalar, std::is_abstract, std::is_const, std::is_empty, std::is_literal_type, std::is_pod, std::is_polymorphic, std::is_signed, std::is_standard_layout, std::is_trivial, std::is_trivially_copyable, std::is_unsigned, std::is_volatile
  • 9. 9 When is no "Rule of Three" required to be implemented? ● If the "Big Three" are not explicitly coded, they'll be generated by the compiler: – The cctor, copy-operator= and the dtor of all the fields in the UDT will be called. – So, if all fields implement the "Big Three", nothing is to do in the UDT. ● Assume following UDT MarriedCouple: – The fields are of type Person. – The used UDT Person implements the "Big Three" and RAII. – MarriedCouple delegates its "Big Three" activities to its Person fields. – => No special member functions need to be implemented in MarriedCouple! class MarriedCouple { Person spouse1; Person spouse2; public: MarriedCouple(const Person& spouse1, const Person& spouse2) : spouse1(spouse1), spouse2(spouse2) {} }; ● If std::string was used in Person instead of char*, the "Big Three" wouldn't need to be implemented explicitly.
  • 10. 10 Lvalues and C++11 Rvalues ● Up to now we've dealt with two sorts of values: – Lvalues: "allowed left from assignment", have an address, controlled by programmers. – Non-lvalues: literals and temporarily created values (temps), have no known address. ● Non-lvalues can only be accepted by non-references andconst&. – The problem: either is a (deep) copy created or a non-modifiable object (const&). ● C++11 closes the gap between lvalues and non-lvalues with rvalues. – Rvalues: modifiable references to non-lvalues controlled by compilers. – Rvalues allow binding non-lvalues to modifiable referencesimplementing move semantics. – With move semantics literals and temps need not to be copied, but can be modified. – In C++11 we can control move-semantics additionally to copy-semantics. – Rvalues enable another new feature in C++: perfect forwarding. ● In C++11 the "Rule of Three" can be extended to the "Rule of Five" with move-semantics. C++11 – rvalue declarator void AcceptsPerson(Person&& person);
  • 11. 11 C++11: Move Semantics ● In C++ there are situations, in which deep copies are not really required. ● Neither the object Person("joe") nor Person("dave") is required after creation. – Their values are just stored in the variable nico and AcceptsPerson()'s parameter respectively. – And then the rvalues Person("joe") and Person("dave") cease to exist. ● The idea is that the memory from the rvalues can be stolen instead of copied. – This is what we call move-semantics instead of copy-semantics. – In C++11 we can write code handling move construction (1) and move assignment (2). AcceptsPerson(Person("dave")); // (1) Move constructor nico = Person("joe"); // (2) Move assignment C++11 – move constructor Person::Person(Person&& original) : name(original.name) /* Stealing! */ { original.name = nullptr; // Ok on rvalue! } /* or: */ // Implementation that forwards to move assignment: Person(Person&& original) { *this = std::move(original); // Declared in <utility>. } C++11 – move assignment operator Person& Person::operator=(Person&& rhs) { if (this != &rhs) { delete [] this->name; this->name = rhs.name; // Stealing! rhs.name = nullptr; // Ok on rvalue! } return *this; } ● By default, most C++ compilers are able to optimize code in a way, so that this kind of superfluous copying is removed. The optimization of mtor and move assignment needs to be deactivated to make the explicitly implemented operators visible (gcc- option: -fno-elide-constructors). ● The function std::move() just converts its argument to a type to reach the correct overload for rvalues.
  • 12. 12 Essential Operators: Operator== and Operator!= – Part I ● What is equality? When do we understand objects to be equal? – Considering nico1 and nico2 as equal, we assume their fields have the same content. – Alas the operator== can't be used on Persons, because this operator isn't defined yet. ● What is identity? – The identity of objects can be specifically answered for C/C++... – ...objects having the same address are identical. Those objects share the same location in memory. – Identity-comparison is intrinsic in C/C++ as pointers are directly supported. It is also called referential equality. – (We already checked for identity to avoid self-assignment) ● Equality: objects have the same content. It is also called structural equality. – Once again in opposite to identity, where objects just have the same address. Person nico1("nico"); Person nico2("nico"); bool equalPersons = nico1 == nico2; // Won't compile for now! bool identicalPersons = &nico1 == &nico2; // Will almost always compile! if (this != &rhs) … // Self-assignment guard. ● What are the results in equalPersons and identicalPersons?
  • 13. 13 Essential Operators: Operator== and Operator!= – Part II ● Good, let's implement operator==: ● And operator!= in terms of operator==: ● The signature of the equality operators shouldn't be a surprise: – Both are binary operators, the member functions accept the rhs and this is the "lhs". – They return a bool result and should be declared const. bool Person::operator==(const Person& rhs) const { if (this != &rhs) { // If rhs is not identical to this, compare the fields: return 0 == std::strcmp(this->name, rhs.name); } return true; // Self-comparison, both objects are identical: always true! } bool Person::operator!=(const Person& rhs) const { return !this->operator==(rhs); // Just negate operator==. } class Person { // (members hidden) public: bool operator==(const Person& rhs) const; bool operator!=(const Person& rhs) const; };
  • 14. 14 Free Operators ● C++ allows operators to be overloaded as – member functions – or as free functions. – Mind that we can only access public members (GetName()) in the free operator==! ● Some operators can only be overloaded as member functions: – type conversion, operator=, operator(), operator[] and operator->. bool operator==(const Person& lhs, const Person& rhs) { // Free function. if (&lhs != &rhs) { // If lhs is not identical to rhs, compare the fields: return 0 == std::strcmp(lhs.GetName(), rhs.GetName()); } return true; // Self-comparison, both objects are identical: always true! } bool Person::operator==(const Person& rhs) const { // Member function if (this != &rhs) { // If rhs is not identical to this, compare the fields: return 0 == std::strcmp(this->name, rhs.name); } return true; // Self-comparison, both objects are identical: always true! }
  • 15. 15 Overload an Operator as free or Member Function? ● Often it depends on whether implicit conversion of the lhs is desired. – E.g. with having Person's operator== as member function we'll have an asymmetry: ● (2) An implicit conversion from const char* to Person works, but conversion of the lhs "nico" to "this" won't work! ● (3) It works as the rhs const char* will be implicitly converted into Person. (2)/(3) are asymmetric! ● (4) Just performs a pointer comparison; operators for fundamental types can't be "overridden". ● (The compiler needed the free operator==(const char*, const Person&) to be present additionally.) – Then with having Person's operator== as only one free function symmetry works: ● The implicit conversion makes (2) and (3) work symmetrically! (4) still doesn't call "our" operator==! Person nico("nico"); Person dave("dave"); bool result = nico == dave; // (1) Ok! Should be clear. bool result2 = "nico" == nico; // (2) Invalid! bool result3 = nico == "nico"; // (3) Ok! bool result4 = "nico" == "nico"; // (4) Oops! Compares two const char*! Person nico("nico"); Person dave("dave"); bool result = nico == dave; // (1) Ok! Should be clear. bool result2 = "nico" == nico; // (2) Ok! bool result3 = nico == "nico"; // (3) Ok! bool result4 = "nico" == "nico"; // (4) Oops! Compares two const char*! bool Person::operator==(const Person& rhs) const { /* pass */ } bool operator==(const Person& lhs, const Person& rhs) { /* pass */ }
  • 16. 16 Friends ● Free functions and operator overloads can be granted access to private members. – This can be done by declaring them as friends of the UDT in the defining UDT: – With granted friendship, the free operator== can access Person's private members: ● When to use friends: – If access to "non-publicised" members is required. – If extra performance is awaited by accessing private members (often fields) directly. – Rule: avoid using friends! They're potentially dangerous as they break encapsulation. // Free function as friend of Person: bool operator==(const Person& lhs, const Person& rhs) { return (&lhs != &rhs) ? 0 == std::strcmp(lhs.name, rhs.name) // private field name : true; } class Person { // (members hidden) // The friendship declares that a free function with this signature // will get access to all members (incl. private members) of // Person. !!This is no declaration of a member function!! friend bool operator==(const Person& lhs, const Person& rhs); };
  • 17. 17 Essential Operators: Operator< and Equivalence ● The implementation of the operator< for Person shouldn't be a surprise: ● The relational comparison operator< is very important in C++! – It can be used to implement all other relational comparison operators: – Esp. the C++ Standard Template Library (STL) exploits the operator< like this. ● E.g. the STL uses the operator< to implement sorting of elements! ● Expressing operator== in terms of operator< is called equivalence comparison. – Equivalence defines equality in terms of the element-order in an ordered sequence. – The term "equivalence" is taken from maths: see "equivalence relations". bool operator<(const Person& lhs, const Person& rhs) { return (&lhs != &rhs) ? 0 > std::strcmp(lhs.name, rhs.name) : false; } Person nico("nico"), dave("dave"); bool result = nico < dave; // >false bool operator>(const Person& lhs, const Person& rhs) { return rhs < lhs; } bool operator==(const Person& lhs, const Person& rhs) { return !(lhs < rhs) && !(rhs < lhs); } bool operator!=(const Person& lhs, const Person& rhs) { return (lhs < rhs) || (rhs < lhs); } bool operator>=(const Person& lhs, const Person& rhs) { return !(lhs < rhs); } bool operator<=(const Person& lhs, const Person& rhs) { return !(rhs < lhs); } ● This example shows all the equivalence operators available in C++. It's important to understand that these operators mustn't be overridden with pointer parameters. This is because we are not allowed to define binary operators only accepting pointers, as this would override the basic equivalence operators the language defines for pointers. It's also questionable (but allowed) to override binary operators in a way that only one of the parameters is a pointer type. - This would lead to a strange syntax that was not awaited by other developers. ● In C++ it is not required to overload all the relational operators separately as shown here. If only the operators < and == are defined for a type, based on this operator the other relational operators can be synthesized by the language. → Just include the h- file <utility> and add a using directive for the namespace std::rel_ops.
  • 18. 18 Essential Operators: Operator<< ● The operator<< is a binary operator, originally expressing left bit shift. – Traditionally it's overloaded to express "sending an object to an output stream" in C++. ● E.g. can we send an object to the standard output-stream std::cout with its operator<<. – We can overload operator<< in "our" UDTs to exploit using streams for "our" UDTs. ● Overloading operator<< as member works, but the order of arguments is odd. ● Let's fix this and discuss this operator's signature. Person nico("nico"); std::cout<<nico; // Invalid! A Person object needs to be the lhs! nico<<std::cout; // Oops! Person's operator<< can't be used // >nico // similar to fundamental types! class Person { // (members hidden) public: std::ostream& operator<<(std::ostream& out) const { return out<<GetName(); } };
  • 19. 19 Essential Operators: Operator<< – the correct Way ● In fact, the lhs of this operator<< needs to of type std::ostream; it can't be coded as member function! – Mind that in a member function the lhs would be this! ● So we've another reason to choose a free operator overload: order of arguments! ● The signature and implementation of operator<< for stream output of a UDT: – It accepts a non-const& to std::ostream as lhs (out) and a const& of the UDT as rhs. ● The lhs is a non-const& because it is modified! The operator<< sends to, or writes to out! ● As the lhs is of type std::ostream, it accepts std::cout as well std::ofstreams (substitution principle). – The implementation just calls operator<< on the passed std::ostream for its fields (1). – It returns the passed std::ostream& to allow chaining syntax (2)! Person nico("nico"); Person dave("dave"); // Ok! rhs as a Person object! std::cout<<nico; // (2) Chaining syntax: std::cout<<" "<<dave<<" : "<<nico<<std::endl; // >dave : nico std::ostream& operator<<(std::ostream& out, const Person& rhs) { return out<<rhs.GetName(); // (1) }
  • 20. 20 Operator Overloading – Tips ● Generally don't overload non-essential operators to have "aesthetic" code! – (Well, it's cool, because we kind of extend C++ by overloading present operators!) – In essence it only makes sense, if we define numeric types! ● And the definition of numeric UDTs is not an every day's job. ● Often it's an interesting school-exercise, but it's rarely done in the wild. – It's often done downright wrong – w/o analogy to fundamental types! ● A little sneakier syntax isn't worth confusing consumers (arcane, not aesthetic) of such UDTs. ● Tips: – Operators modifying this/lhs should return a non-const& to this/lhs to allow chaining. – Some binary operators create and return a new instance of the UDT, no reference. – Keep operator and compound assignment (e.g. + and +=) consistent. ● C++ won't infer compound assignment for us. – Never overload &&, || and , (comma/sequence operator) in C++! – Sometimes overloads of the operators++/--/</== are required for the STL to work. – Use free function operator overloads to exploit order of arguments or type conversion. ● The operators =, & and , (and the dctor and non- virtual dtor) have predefined meanings.