-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
134 lines (106 loc) · 5 KB
/
main.cpp
File metadata and controls
134 lines (106 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <IntricatePointers/IntricatePointers.hpp>
using namespace Intricate;
class ExampleClass
{
public:
constexpr ExampleClass(float f1, float f2, int64_t i1) noexcept : m_F1(f1), m_F2(f2), m_I1(i1) { };
ExampleClass() = default;
~ExampleClass() noexcept
{
std::cout << "ExampleClass .dtor called on " << this << '\n';
}
constexpr float GetF1() const noexcept { return m_F1; }
constexpr float GetF2() const noexcept { return m_F2; }
constexpr int64_t GetI1() const noexcept { return m_I1; }
private:
float m_F1;
float m_F2;
int64_t m_I1;
};
class BaseClass
{
public:
constexpr BaseClass(int number) noexcept : m_Number(number) { };
BaseClass() = default;
// This destructor must be marked virtual to allow the destructors of any child classes to also be called when this object is free'd.
virtual ~BaseClass() noexcept
{
std::cout << "BaseClass .dtor called on " << this << '\n';
}
virtual void DoSomething() const noexcept = 0;
virtual void DoSomethingElse() const noexcept = 0;
constexpr int GetNumber() const noexcept { return m_Number; }
protected:
int m_Number;
};
class DerivedClass : public BaseClass
{
public:
constexpr DerivedClass(int number) noexcept : BaseClass(number) { };
// This destructor will always be called before BaseClass's destructor.
virtual ~DerivedClass() noexcept
{
std::cout << "DerivedClass .dtor called on " << this << '\n';
}
virtual void DoSomething() const noexcept override
{
std::cout << "DerivedClass::DoSomething() called on " << this << '\n';
}
virtual void DoSomethingElse() const noexcept override
{
std::cout << "DerivedClass::DoSomethingElse() called on " << this << '\n';
}
};
int main(int argc, char** argv)
{
std::cout << "----------------------------------------------------------------\n";
std::cout << "Example-Ref\n";
std::cout << "----------------------------------------------------------------\n\n";
// Creates a reference counted pointer to a newly heap-allocated and constructed instance of 'ExampleClass'
Ref<ExampleClass> constructedRef = CreateRef<ExampleClass>(23.5f, 19.2f, INT64_MAX);
// Retrieve the reference count (use_count) of the pointer
std::cout << "constructedRef ref-count: " << constructedRef.RefCount() << '\n';
// Increment the ref count by assigning it to a new object
Ref<ExampleClass> constructedRefCopy = constructedRef;
std::cout << "constructedRef ref-count after new assignment: " << constructedRef.RefCount() << '\n';
// Access the data of constructedRef
std::cout << "constructedRef F1: " << constructedRef->GetF1() << '\n';
std::cout << "constructedRef F2: " << constructedRef->GetF2() << '\n';
std::cout << "constructedRef I1: " << constructedRef->GetI1() << '\n';
// When releasing the reference held by constructedRefCopy, the underlying data pointed to by constructedRef does not
// get free'd yet since the reference count hasn't yet hit 0
constructedRefCopy = nullptr;
std::cout << "constructedRef ref-count after release: " << constructedRef.RefCount() << '\n';
// Once we release the reference held by constructedRef, the reference count will hit 0 and the data will be free'd
constructedRef = nullptr;
// Create a new ref of type 'BaseClass' that actually points to a 'DerivedClass'
Ref<BaseClass> baseClassRef = CreateRef<DerivedClass>(21);
baseClassRef->DoSomething();
baseClassRef->DoSomethingElse();
std::cout << "baseClassRef Number: " << baseClassRef->GetNumber() << '\n';
// Calling Reset will decrement the reference count, in this instance since this pointer is unique (only holds 1 reference)
// the count will hit 0 and the memory will be free'd. This will call the DerivedClass's and BaseClass's destructors.
baseClassRef.Reset();
// When 'scopedRef' falls out of scope, the reference count on this object will hit 0 causing it to be free'd.
{
auto scopedRef = CreateRef<ExampleClass>(22.0f, -65.0f, INT64_MIN);
std::cout << "scopedRef address: " << scopedRef << '\n';
std::cout << "scopedRef F1: " << scopedRef->GetF1() << '\n';
std::cout << "scopedRef F2: " << scopedRef->GetF2() << '\n';
std::cout << "scopedRef I1: " << scopedRef->GetI1() << '\n';
}
// Create a ref to an int and print the int by dereferencing the smart pointer.
Ref<int> intRef = CreateRef<int>(11);
std::cout << "intRef: " << *intRef << '\n';
std::cout << "intRef address: " << intRef << '\n';
// Release ownership of the pointer
int* intPtr = intRef.Release();
std::cout << "intRef address after release: " << intRef << '\n';
std::cout << "intPtr: " << *intPtr << '\n';
std::cout << "intPtr address: " << intPtr << '\n';
// Since intRef was allocated with new and we released its ownership of the pointer, we have to manually clean it up by using delete.
delete intPtr;
std::cin.get();
return 0;
}