forked from HPI-Artificial-Intelligence-Teaching/24-pt2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f5b3fb9
commit 27e6ae8
Showing
10 changed files
with
553 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
TARGETS = types pointers const overloading copymove template mystring virtual | ||
CXX = g++ | ||
CPPFLAGS = -std=c++17 | ||
LDLIBS=-lm | ||
|
||
all: $(TARGETS) | ||
|
||
clean: | ||
$(RM) $(TARGETS) | ||
|
||
.PHONY: all clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
// This function double the references given to it | ||
void double_number(int& x) { | ||
x *= 2; | ||
return; | ||
} | ||
|
||
// This function checks that the number passed by const-reference is even | ||
bool is_even(const int& x) { | ||
// This is a compile time error as the function tries to change the value that x refers to | ||
// x += 2; | ||
return (x % 2 == 0); | ||
} | ||
|
||
// main entry point of the program | ||
int main(void) { | ||
int x{10}, y{42}; | ||
const int z{66}; | ||
|
||
// This is not ok b/c of the const-ness of z | ||
// z = 13; | ||
|
||
int* const p{&x}; | ||
cout << setw(20) << "*p = " << *p << endl; | ||
*p += 17; | ||
cout << setw(20) << "*p + 17 = " << *p << endl; | ||
|
||
// This does not compile b/c the pointer is const | ||
// p = &y; | ||
|
||
const int* const p2{&y}; | ||
cout << setw(20) << "*p2 = " << *p2 << endl; | ||
// This is no longer possible b/c the pointer p2 is const pointing to a const int! | ||
// *p2 += 17; | ||
// cout << setw(20) << "*p + 17 = " << *p2 << endl; | ||
|
||
double_number(*p); | ||
cout << setw(20) << "*p (after double) = " << *p << endl; | ||
|
||
// This call is not possible because the function double_number MIGHT change the value (it's constness does not promise not to!) | ||
// double_number(*p2); | ||
// cout << setw(20) << "*p2 (after double) = " << *p2 << endl; | ||
|
||
cout << setw(20) << "*p is even = " << is_even(*p) << endl; | ||
// This call IS possible because the function is_even promises in its signature not to change the value it's given! | ||
cout << setw(20) << "*p2 is even = " << is_even(*p2) << endl; | ||
|
||
return (0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
class MyInt { | ||
int value = 0; // actual integer value | ||
public: | ||
MyInt(int i) : value{i} { | ||
cout << "Ordinary constructor MyInt(int = " << i << ")" << endl; | ||
} | ||
MyInt() { | ||
cout << "Default constructor MyInt()" << endl; | ||
} | ||
MyInt(const MyInt& mi) : value{mi.value} { | ||
cout << "Copy constructor MyInt(MyInt& = " << mi.value << ")" << endl; | ||
} | ||
MyInt(MyInt&& mi) : value{mi.value} { | ||
cout << "Move constructor MyInt(MyInt&& = " << mi.value << ")" << endl; | ||
} | ||
MyInt& operator=(const MyInt& mi) { | ||
cout << "Copy assignment MyInt& operator=(const MyInt& = " << mi.value << ")" << endl; | ||
value = mi.value; | ||
return (*this); | ||
} | ||
MyInt& operator=(MyInt&& mi) { | ||
cout << "Move assignment MyInt& operator=(MyInt&& = " << mi.value << ")" << endl; | ||
value = mi.value; | ||
return (*this); | ||
} | ||
~MyInt() { | ||
cout << "Destructor ~MyInt(= " << value << ")" << endl; | ||
} | ||
|
||
int val() { return value; } | ||
}; | ||
|
||
MyInt f(MyInt& mi) { | ||
cout << "\t\tMyInt tmp { mi.val() + 25 };" << endl; | ||
MyInt tmp{mi.val() + 25}; | ||
|
||
cout << "\t\treturn (tmp);" << endl; | ||
return (tmp); | ||
} | ||
|
||
// main entry point of the program | ||
int main(void) { | ||
cout << "\tMyInt m1;" << endl; | ||
MyInt m1; | ||
cout << "\tMyInt m2 { 10 };" << endl; | ||
MyInt m2{10}; | ||
cout << "\tMyInt m3 = 12;" << endl; | ||
MyInt m3 = 12; | ||
cout << "\tMyInt m4 { m3 };" << endl; | ||
MyInt m4{m3}; | ||
|
||
cout << "\tm1 = m2;" << endl; | ||
m1 = m2; | ||
|
||
cout << "\tm3 = f(m1);" << endl; | ||
m3 = f(m1); | ||
|
||
cout << "\tMyInt m5{move(f(m3))};" << endl; | ||
MyInt m5{move(f(m3))}; | ||
|
||
cout << "\treturn (0);" << endl; | ||
return (0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
// A class that represents strings of fixed length efficiently | ||
class MyString { | ||
char* str; // the pointer to the actual (non-zero-terminated!) string | ||
int len; // the length of the string | ||
public: | ||
// default constructor | ||
MyString() : str(nullptr), len(0) {} | ||
|
||
// default constructor for undefined string with fixed length | ||
MyString(const int l) { | ||
if (l < 0) exit(-1); | ||
len = l; | ||
str = new char[len]; | ||
} | ||
|
||
// constructs a string from a C-style string | ||
MyString(const char* s) { | ||
// counts the length of the C-string (without the terminating '\0') | ||
len = 0; | ||
for (int i = 0; s[i]; i++, len++) | ||
; | ||
|
||
// allocate the memory for all the characters | ||
str = new char[len]; | ||
|
||
// copy all the characters | ||
for (int i = 0; i < len; i++) | ||
str[i] = s[i]; | ||
} | ||
// copy constructor | ||
MyString(const MyString& ms) : len(ms.len) { | ||
// allocate the memory for all the characters | ||
str = new char[len]; | ||
|
||
// copy all the characters | ||
for (int i = 0; i < len; i++) | ||
str[i] = ms.str[i]; | ||
} | ||
// move constructor | ||
MyString(MyString&& ms) : len(ms.len), str(ms.str) { | ||
ms.len = 0; | ||
ms.str = nullptr; | ||
} | ||
// destructor | ||
~MyString() { | ||
delete[] str; | ||
} | ||
// copy assignment operator | ||
MyString& operator=(const MyString& ms) { | ||
// free the existing string | ||
delete[] str; | ||
|
||
// copy the length of the assigned string | ||
len = ms.len; | ||
|
||
// allocate the memory for all the characters | ||
str = new char[len]; | ||
|
||
// copy all the characters | ||
for (int i = 0; i < len; i++) | ||
str[i] = ms.str[i]; | ||
return (*this); | ||
} | ||
// move assignment operator | ||
MyString& operator=(MyString&& ms) { | ||
// free the existing string | ||
delete[] str; | ||
|
||
// copy the length of the assigned string | ||
len = ms.len; | ||
|
||
// copy the pointer from the moved MyString ... | ||
str = ms.str; | ||
|
||
// ... and invalidate the moved data | ||
ms.len = 0; | ||
ms.str = nullptr; | ||
return (*this); | ||
} | ||
// index operator overload | ||
char& operator[](size_t pos) const { | ||
if (pos < 0 || pos > (len - 1)) | ||
exit(-1); | ||
return (str[pos]); | ||
} | ||
|
||
// returns the length of the string | ||
int length() const { return len; } | ||
|
||
// output the string on an output stream | ||
void print() const { | ||
for (int i = 0; i < len; i++) | ||
cout << str[i]; | ||
return; | ||
} | ||
}; | ||
|
||
// implementation of the stream output of MyString | ||
ostream& operator<<(ostream& out, const MyString& ms) { | ||
for (int i = 0; i < ms.length(); i++) | ||
out << ms[i]; | ||
return (out); | ||
} | ||
|
||
// string concatenation as the addition operation | ||
MyString operator+(const MyString& lhs, const MyString& rhs) { | ||
MyString out(lhs.length() + rhs.length()); | ||
|
||
// first copy the characters of the left hands side ... | ||
int i = 0; | ||
for (int j = 0; j < lhs.length(); j++, i++) | ||
out[i] = lhs[j]; | ||
// ... and then copy the characters of the right hand side | ||
for (int j = 0; j < rhs.length(); j++, i++) | ||
out[i] = rhs[j]; | ||
|
||
return (out); | ||
} | ||
|
||
// Transforms a string to upper case | ||
MyString to_upper(const MyString& ms) { | ||
MyString tmp = ms; | ||
|
||
for (int i = 0; i < tmp.length(); i++) | ||
tmp[i] = toupper(tmp[i]); | ||
return (tmp); | ||
} | ||
|
||
// main entry point of the program | ||
int main(void) { | ||
MyString s1("Hello world!"); | ||
MyString s2(s1); | ||
MyString s3; | ||
MyString s4 = "Hello"; | ||
MyString s5 = " World!"; | ||
MyString s6; | ||
|
||
// change one character in the first string | ||
s1[5] = ','; | ||
|
||
// then set the default initialized string to the result of an operation | ||
s3 = to_upper(s2); | ||
|
||
// and then concatenate two string | ||
s6 = s4 + s5; | ||
|
||
cout << setw(10) << "s1 = "; | ||
s1.print(); | ||
cout << endl; | ||
|
||
cout << setw(10) << "s2 = " << s2 << endl; | ||
cout << setw(10) << "s3 = " << s3 << endl; | ||
cout << setw(10) << "s4 = " << s4 << endl; | ||
cout << setw(10) << "s5 = " << s5 << endl; | ||
cout << setw(10) << "s6 = " << s6 << endl; | ||
|
||
return (0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
// A simple struct to demonstrate operator overloading | ||
struct Rational { | ||
int p; | ||
int q; | ||
|
||
// Operator overloading for a typecast operator | ||
operator double() const { return ((double)p / (double)q); } | ||
}; | ||
|
||
// overloading of the addition operator | ||
Rational operator+(Rational const& a, Rational const& b) { | ||
Rational c = {a.p * b.q + b.p * a.q, a.q * b.q}; | ||
return (c); | ||
} | ||
|
||
// overloading of the multiplication operator | ||
Rational operator*(Rational const& a, Rational const& b) { | ||
Rational c = {a.p * b.q, a.q * b.q}; | ||
return (c); | ||
} | ||
|
||
// prints a rational number on the output stream | ||
void print_rational(const Rational& r, int width = 10) { | ||
cout << setw(width) << (double)r.p / (double)r.q; | ||
return; | ||
} | ||
|
||
// integer version of the function f | ||
int f(int x, int y) { | ||
return (x + y); | ||
} | ||
|
||
// double version of the function f | ||
int f(double x, double y) { | ||
return ((int)(x * y)); | ||
} | ||
|
||
// main entry point of the program | ||
int main(void) { | ||
cout << setw(20) << "f(4,3) = " << f(4, 3) << endl; | ||
cout << setw(20) << "f(4.0,3.0) = " << f(4.0, 3.0) << endl; | ||
cout << setw(20) << "f(5,(int) 6.0) = " << f(5, (int)6.0) << endl; | ||
cout << setw(20) << "f(5.0,(double) 6) = " << f(5.0, (double)6) << endl; | ||
|
||
Rational a = {1, 2}; | ||
Rational b = {1, 4}; | ||
Rational c = a + b; | ||
Rational d = a * b; | ||
|
||
cout << setw(20) << "1/2 + 1/4 = " << (double)c.p / (double)c.q << endl; | ||
cout << setw(20) << "1/2 * 1/4 = " << a * b << endl; | ||
cout << setw(20) << "1/2 * 1/4 = "; | ||
print_rational(d); | ||
cout << endl; | ||
cout << setw(20) << "1/2 * 1/4 = "; | ||
print_rational(d, 5); | ||
cout << endl; | ||
|
||
return (0); | ||
} |
Oops, something went wrong.