Skip to content

Commit cbcddde

Browse files
committed
Add Overloading Examples
1 parent 797f064 commit cbcddde

13 files changed

Lines changed: 685 additions & 1 deletion

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,18 @@ set(APP_SOURCES
154154
"src/core/datatypes/smart_pointer/Unique.cpp"
155155
"src/core/datatypes/smart_pointer/Shared.cpp"
156156
"src/core/datatypes/smart_pointer/Weak.cpp"
157+
## Overloading
158+
"src/core/overloading/ArithmeticOperator.cpp"
159+
"src/core/overloading/IOOperator.cpp"
160+
"src/core/overloading/UnaryOperator.cpp"
161+
"src/core/overloading/ComparisonOperator.cpp"
162+
"src/core/overloading/InDecOperator.cpp"
163+
"src/core/overloading/SubscriptOperator.cpp"
164+
"src/core/overloading/ParenthesisOperator.cpp"
165+
"src/core/overloading/TypeCast.cpp"
166+
"src/core/overloading/AssignmentOperator.cpp"
167+
"src/core/overloading/ClassMemberAccessOperator.cpp"
168+
"src/core/overloading/AllocationOperator.cpp"
157169
)
158170

159171
# Test files

src/core/datatypes/class/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
## 1. Friend
2+
- Friend declaration (classes and functions) allows certain classes or functions to access the private and protected members of another class.
3+
24
### 1.1. Non Member Function
35
- It serves the same kind of role as the package access specifier in Java.
46
- `a << b` C++ tries in this order:
@@ -9,7 +11,7 @@
911
X OP Y
1012
operator OP (type_of_X, type_of_Y)
1113
```
12-
### 1.2. Member Function
14+
### 1.2. Member of Another Class:
1315
- It give access to only once specific function.
1416
### 1.3. Class
1517
- Friend Class : I trust this class to see my private data
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// cppcheck-suppress-file [functionConst]
2+
3+
// Overloading operator new, delete
4+
// Debug
5+
6+
#include <iostream>
7+
#include "ExampleRegistry.h"
8+
namespace {
9+
10+
class IntCollection {
11+
private:
12+
int m_data[3]{10, 20, 30};
13+
14+
public:
15+
class Iterator {
16+
private:
17+
int* m_ptr;
18+
19+
public:
20+
explicit Iterator(int* ptr) : m_ptr(ptr) {}
21+
22+
int& operator*() { return *m_ptr; }
23+
24+
int* operator->() { return m_ptr; }
25+
26+
Iterator& operator++() {
27+
++m_ptr;
28+
return *this;
29+
}
30+
31+
bool operator!=(const Iterator& other) const {
32+
return m_ptr != other.m_ptr;
33+
}
34+
};
35+
36+
Iterator begin() { return Iterator(m_data); }
37+
Iterator end() { return Iterator(m_data + 3); }
38+
39+
// int* a = new int;
40+
void* operator new(size_t size) {
41+
std::cout << "void* operator new(size_t size)\n";
42+
// void* p = ::operator new(size);
43+
void* p = malloc(size);
44+
if (!p)
45+
throw std::bad_alloc();
46+
return p;
47+
}
48+
49+
// delete a
50+
void operator delete(void* p) {
51+
std::cout << "void operator delete(void* p)\n";
52+
free(p);
53+
}
54+
55+
// int* as = new int[100]
56+
void* operator new[](size_t size) {
57+
std::cout << "void* operator new[](size_t size)\n";
58+
void* p = malloc(size);
59+
if (!p)
60+
throw std::bad_alloc();
61+
return p;
62+
}
63+
64+
// delete []as;
65+
void operator delete[](void* p) {
66+
std::cout << "void operator delete[](void* p)\n";
67+
free(p);
68+
}
69+
};
70+
71+
void run() {
72+
IntCollection* col = new IntCollection;
73+
74+
for (auto it = col->begin(); it != col->end(); ++it) {
75+
std::cout << *it << '\n';
76+
}
77+
78+
delete col;
79+
80+
IntCollection* cols = new IntCollection[10];
81+
for (int i = 0; i < 10; ++i) {
82+
for (auto it = cols[i].begin(); it != cols[i].end(); ++it) {
83+
std::cout << *it << '\n';
84+
}
85+
}
86+
delete[] cols;
87+
}
88+
} // namespace
89+
90+
class AllocationOperator : public IExample {
91+
public:
92+
std::string group() const override { return "core/overloading"; }
93+
std::string name() const override { return "AllocationOperator"; }
94+
std::string description() const override { return ""; }
95+
96+
void execute() override { run(); }
97+
};
98+
99+
REGISTER_EXAMPLE(AllocationOperator, "core/overloading", "AllocationOperator");
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// cppcheck-suppress-file[]
2+
// + - * /
3+
#include <iostream>
4+
#include "ExampleRegistry.h"
5+
6+
namespace {
7+
class Cents {
8+
private:
9+
int m_cents{};
10+
11+
public:
12+
explicit Cents(int cents) : m_cents{cents} {}
13+
int getCents() const { return m_cents; }
14+
15+
// Problem: A member operator only works when the left-hand operand is an object of the class (e.g., Cents).
16+
// Cents sum = 5 + s1;
17+
// int.operator+(5)
18+
// => error
19+
// Cents operator+(const Cents& other) {
20+
// return Cents{this->getCents() + other.getCents()};
21+
// }
22+
23+
// For operands of different types
24+
friend Cents operator+(int v1, const Cents& c2) {
25+
return Cents{v1 + c2.getCents()};
26+
}
27+
28+
friend Cents operator+(const Cents& c1, int v2) {
29+
return Cents{v2 + c1.getCents()};
30+
}
31+
32+
// ArithmeticOperator operators
33+
friend Cents operator+(const Cents& c1, const Cents& c2) {
34+
return Cents{c1.getCents() + c2.getCents()};
35+
}
36+
37+
friend Cents operator-(const Cents& c1, const Cents& c2) {
38+
return Cents{c1.getCents() - c2.getCents()};
39+
}
40+
41+
friend Cents operator*(const Cents& c1, const Cents& c2) {
42+
return Cents{c1.getCents() * c2.getCents()};
43+
}
44+
45+
friend Cents operator/(const Cents& c1, const Cents& c2) {
46+
return Cents{c1.getCents() / c2.getCents()};
47+
}
48+
};
49+
50+
void run() {
51+
Cents c1{25};
52+
Cents c2{75};
53+
54+
// Sum
55+
Cents sum = c1 + c2;
56+
Cents sum2 = operator+(125, c2);
57+
std::cout << "Sum: " << sum.getCents() << " " << sum2.getCents() << std::endl;
58+
59+
// Sub
60+
Cents sub = c1 - c2;
61+
std::cout << "Sub: " << sub.getCents() << std::endl;
62+
63+
// Div
64+
Cents div = c1 / c2;
65+
std::cout << "Div: " << div.getCents() << std::endl;
66+
67+
// Mul
68+
Cents mul = c1 * c2;
69+
std::cout << "Mul: " << mul.getCents() << std::endl;
70+
}
71+
} // namespace
72+
73+
class ArithmeticOperator : public IExample {
74+
public:
75+
std::string group() const override { return "core/overloading"; }
76+
std::string name() const override { return "ArithmeticOperator"; }
77+
std::string description() const override { return ""; }
78+
79+
void execute() override { run(); }
80+
};
81+
82+
REGISTER_EXAMPLE(ArithmeticOperator, "core/overloading", "ArithmeticOperator");
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// cppcheck-suppress-file [unreadVariable]
2+
3+
// Overloading operator=
4+
5+
#include <iostream>
6+
#include "ExampleRegistry.h"
7+
8+
namespace {
9+
class Cents {
10+
private:
11+
int m_cents{};
12+
13+
public:
14+
explicit Cents(int cents = 0) : m_cents{cents} {}
15+
16+
int getCents() const { return m_cents; }
17+
void setCents(int cents) { m_cents = cents; }
18+
19+
// Copy constructor
20+
Cents(const Cents& other) {
21+
std::cout << "Cents(const Cents& other)\n";
22+
m_cents = other.m_cents;
23+
}
24+
25+
// Overload copy assignment
26+
Cents& operator=(const Cents& cents) {
27+
// do the copy
28+
std::cout << "Cents& operator=(const Cents& cents)\n";
29+
m_cents = cents.m_cents;
30+
return *this;
31+
}
32+
};
33+
34+
void run() {
35+
Cents c1{100};
36+
Cents c2;
37+
c2 = c1; // calls overloaded copy assignment
38+
Cents c3 = c1; // calls copy constructor because c3 didn't exist yet
39+
}
40+
} // namespace
41+
42+
class AssignmentOperator : public IExample {
43+
public:
44+
std::string group() const override { return "core/overloading"; }
45+
std::string name() const override { return "AssignmentOperator"; }
46+
std::string description() const override { return ""; }
47+
48+
void execute() override { run(); }
49+
};
50+
51+
REGISTER_EXAMPLE(AssignmentOperator, "core/overloading", "AssignmentOperator");
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// cppcheck-suppress-file []
2+
3+
// Overloading operator-> *.
4+
// Collection item
5+
6+
#include <iostream>
7+
#include "ExampleRegistry.h"
8+
namespace {
9+
10+
class IntCollection {
11+
private:
12+
int m_data[3]{10, 20, 30};
13+
14+
public:
15+
class Iterator {
16+
private:
17+
int* m_ptr;
18+
19+
public:
20+
explicit Iterator(int* ptr) : m_ptr(ptr) {}
21+
22+
int& operator*() {
23+
std::cout << "int& operator*()\n";
24+
return *m_ptr;
25+
}
26+
27+
int* operator->() {
28+
std::cout << "int* operator->()\n";
29+
return m_ptr;
30+
}
31+
32+
Iterator& operator++() {
33+
++m_ptr;
34+
return *this;
35+
}
36+
37+
bool operator!=(const Iterator& other) const {
38+
return m_ptr != other.m_ptr;
39+
}
40+
};
41+
42+
Iterator begin() { return Iterator(m_data); }
43+
Iterator end() { return Iterator(m_data + 3); }
44+
};
45+
46+
void run() {
47+
IntCollection col;
48+
49+
for (auto it = col.begin(); it != col.end(); ++it) {
50+
std::cout << *it << '\n';
51+
}
52+
}
53+
} // namespace
54+
55+
class ClassMemberAccessOperator : public IExample {
56+
public:
57+
std::string group() const override { return "core/overloading"; }
58+
std::string name() const override { return "ClassMemberAccessOperator"; }
59+
std::string description() const override { return ""; }
60+
61+
void execute() override { run(); }
62+
};
63+
64+
REGISTER_EXAMPLE(ClassMemberAccessOperator, "core/overloading",
65+
"ClassMemberAccessOperator");
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// cppcheck-suppress-file[]
2+
3+
#include <iostream>
4+
#include "ExampleRegistry.h"
5+
6+
namespace {
7+
class Cents {
8+
private:
9+
int m_cents{};
10+
11+
public:
12+
explicit Cents(int cents) : m_cents{cents} {}
13+
int getCents() const { return m_cents; }
14+
15+
auto operator<=> (const Cents&) const = default; // std 20
16+
// friend bool operator== (const Cents& c1, const Cents& c2) { return c1.m_cents == c2.m_cents; }
17+
// friend bool operator!= (const Cents& c1, const Cents& c2) { return !(operator==(c1, c2)); }
18+
19+
// friend bool operator< (const Cents& c1, const Cents& c2) { return c1.m_cents < c2.m_cents; }
20+
// friend bool operator> (const Cents& c1, const Cents& c2) { return operator<(c2, c1); }
21+
22+
// friend bool operator<= (const Cents& c1, const Cents& c2) { return !(operator>(c1, c2)); }
23+
// friend bool operator>= (const Cents& c1, const Cents& c2) { return !(operator<(c1, c2)); }
24+
};
25+
26+
void run() {
27+
Cents pt1{25};
28+
Cents pt2{30};
29+
std::cout << std::boolalpha << (pt1 == pt2) << ' ' // false
30+
<< (pt1 != pt2) << ' ' // true
31+
<< (pt1 < pt2) << ' ' // true
32+
<< (pt1 <= pt2) << ' ' // true
33+
<< (pt1 > pt2) << ' ' // false
34+
<< (pt1 >= pt2) << ' '; // false
35+
}
36+
} // namespace
37+
38+
class ComparisonOperator : public IExample {
39+
public:
40+
std::string group() const override { return "core/overloading"; }
41+
std::string name() const override { return "ComparisonOperator"; }
42+
std::string description() const override { return ""; }
43+
44+
void execute() override { run(); }
45+
};
46+
47+
REGISTER_EXAMPLE(ComparisonOperator, "core/overloading", "ComparisonOperator");

0 commit comments

Comments
 (0)