-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdumbpointer.h
More file actions
125 lines (102 loc) · 3.42 KB
/
dumbpointer.h
File metadata and controls
125 lines (102 loc) · 3.42 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
// ©2013 Sqeaky
// This is distibuted under the WTFPL, see COPYING.md for details.
#ifndef dumbpointer_h
#define dumbpointer_h
#include "vehicletree.h"
///////////////////////////////////////////////////////////////////////////
// Templates and casting to derived types.
// Here Is the default for a the dumbed down smart pointer(hereafter dumb pointer)
template <typename A, typename B>
class TemplateImpliesType
{
private:
B* ValuePointer;
public:
TemplateImpliesType(B* Init)
: ValuePointer(Init)
{}
A* Get()
{
cout << "Returning a B* as an A*." << endl;
return dynamic_cast<A*>(ValuePointer);
}
};
// If the instantiation type matches the return type, this will get used instead.
template <typename A>
class TemplateImpliesType <A,A>
{
private:
A* ValuePointer;
public:
TemplateImpliesType(A* Init)
: ValuePointer(Init)
{}
A* Get()
{
cout << "Returning an A*." << endl;
return ValuePointer;
}
};
// This one uses a default template parameter to allow a dumb-pointer to be implemented with the support for casting
// between types but not complicate matters by requiring a separate class.
template <typename A, typename B=A>
class TemplateImpliesType2
{
private:
B* ValuePointer;
template <typename X, typename Y> // This has to be a class to detect types at compile time.
class GetImpl
{
public:
static X* Get(Y* Results)
{
cout << "Returning a B* as an A*." << endl;
return dynamic_cast<A*>(Results);
}
};
template <typename X>
class GetImpl <X,X>
{
public:
static X* Get(X* Results)
{
cout << "Returning an A* as an A*." << endl;
return Results;
}
};
public:
TemplateImpliesType2(B* Init)
: ValuePointer(Init)
{}
A* Get()
{
return GetImpl<A,B>::Get(ValuePointer);
}
};
void TemplatesAndInferredCasting()
{
cout << "Creating some vehicles." << endl;
Car TargetA;
Chevy TargetB;
cout << endl;
cout << "Stuffing vehicles into class templates that may obscure their types." << endl;
TemplateImpliesType<Car,Car> ATest(&TargetA);
TemplateImpliesType<Car,Chevy> BTest(&TargetB);
ATest.Get()->startEngine();
BTest.Get()->startEngine();
cout << endl;
cout << "Stuffing vehicles into class templates that may obscure their types and gets the inheritance hiearchy backwards. But it would not compile" << endl;
TemplateImpliesType<Chevy,Car> AwTest(&TargetB);
//error: invalid conversion from Car* to Chevy* [-fpermissive]
//TemplateImpliesType<Chevy,Chevy> BwTest(&TargetA);
AwTest.Get()->startEngine();
//BwTest.Get()->startEngine();
cout << endl;
cout << "Stuffing vehicle into type that can handle multiple type and doesn't care." << endl;
TemplateImpliesType2<Car> A2Test(&TargetA);
TemplateImpliesType2<Car,Chevy> B2Test(&TargetB);
A2Test.Get()->openGasCap();
B2Test.Get()->openGasCap();
cout << endl;
}
#endif //dumbpointer_h