PhD @ UniPi
Software Engineer @ Bloomberg
jalonsoloren@bloomberg.net
jaimealonso
www.linkedin.com/in/jaimealonsolorenzo
Let's abbreviate Unexpected Behaviour as UXB
UXB occurs when a program does not perform what the programmer initially intended and instead causes an undesired result.
int a[10];
...
a[5] = 1;
5[a] = 1;
The C standard defines the [] operator as follows:
a[5] == *(a + 5)
Therefore 5[a] will evaluate to:
*(5 + a) == *(a + 5)
“ Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.”
Wikipedia
class Account {
public:
virtual void deposit(int amount) {
accountBalance += amount;
}
virtual void balance() {
std::cout << "Balance: " << accountBalance << std::endl;
}
protected:
int accountBalance = 0;
};
class EmployeeAccount : public Account {
private:
virtual void paySalary() { accountBalance += 1000; }
};
int main()
Account a;
a.deposit(100);
a.balance(); // 100
EmployeeAccount e;
e.paySalary(); // won't compile
}
class Account {
public:
virtual void deposit(int amount) {
accountBalance += amount;
}
virtual void balance() {
std::cout << "Balance: " << accountBalance << std::endl;
}
virtual void paySalary() {}
protected:
int accountBalance = 0;
};
class EmployeeAccount : public Account {
private:
virtual void paySalary() { accountBalance += 1000; }
};
int main()
Account a;
a.deposit(100);
a.balance(); // 100
EmployeeAccount e;
e.paySalary(); // won't compile
Account* ea = &e;
ea->paySalary();
a.balance(); // 1000
}
while(true){
ea->paySalary();
}
size_t x = 10;
while(0<--x);
std::cout << x << std::endl; // 0
<-- is not an operator
It is equivalent to:
while(0 < (--x));
wp----->size();
The long arrow is not a single operator, but a combination of multiple operators.
Here it is a normal -> operator and the postfix decrement operator --
((wp--)--)->length();
How can we overload them?
void greeting(std::string str) {
std::cout << str << std::endl;
}
void greeting(bool german) {
if(german)
std::cout << "Hallo Welt!" << std::endl;
else
std::cout << "Hello World!" << std::endl;
}
greeting("Ciao mondo!"); // Ciao mondo!
greeting("Ciao mondo!"); // Hallo Welt!
using namespace std::string_literals;
std::variant<int, bool, std::string> a = "Hello World!"s;
// Now we get the expected std::string type
#include <vector>
#include <algorithm>
bool isOne(int a) { return a == 1; }
bool isOne(double b) { return a == 1.0; }
int main()
{
std::vector<int> my_vec{1,2,3,4};
// doesn't compile
std::find_if(my_vec.begin(), my_vec.end(), isOne);
}
* https://www.fluentcpp.com/2017/08/01/overloaded-functions-stl/
struct wrapper
{
template<typename T>
bool operator()(T&& a)
{
return isOne(a);
}
};
std::find_if(my_vec.begin(), my_vec.end(), wrapper());
std::find_if(my_vec.begin(), my_vec.end(),
[](auto&& a){ return isOne(a); });
http://cpp-unexpected-behaviour.github.io/meetingcpp2017