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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
#include <stdio.h>
////////////////////////////////////////////////////////////////////////////////
template <typename ObjectType, typename ValueType>
class property
{
public :
// Type de pointeur de fonction pour Property Get
typedef ValueType (ObjectType::*PGETTER)(void);
// Type de pointeur de fonction pour Property Set
typedef void (ObjectType::*PSETTER)(ValueType value);
private :
// Instance de l'objet contenant la propriété à gérer
ObjectType *m_pObject;
// Pointeur de la fonction Property Set
PSETTER Set;
// Pointeur de la fonction Property Get
PGETTER Get;
public:
// Constructeur par défaut
property(void)
{
m_pObject = NULL;
Set = NULL;
Get = NULL;
}
// Initialisation de la propriété
// object : Instance de l'object contenant la propriété.
// pGet : Pointeur vers la fonction de récupération de la valeur de la propriété.
// pSet : Pointeur vers la fonction d'affectation de la valeur de la propriété.
void Setup(ObjectType *object, PGETTER pGet, PSETTER pSet)
{
// TODO : Vérifier les paramètres et gérer les exceptions
m_pObject = object;
this->Set = pSet;
this->Get = pGet;
}
// Vérifier l'accès en lecture
bool CanRead(void)
{
return (this->GSet != NULL);
}
// Vérifier l'accès en écriture
bool CanWrite(void)
{
return (this->Set != NULL);
}
// Surcharger le retour de la valeur casté au type de la propriété
operator ValueType()
{
return (m_pObject->*Get)();
}
// Surcharger l'affectation
ValueType operator =(const ValueType& value)
{
// TODO : Vérifier les paramètres et gérer les exceptions
if(this->Set == NULL) throw "Propriété en lecture seule!";
(m_pObject->*Set)(value);
return (m_pObject->*Get)();
}
// Comparer les objets et non pas les classe property
bool operator==(const ValueType& value)
{
// TODO : Vérifier les paramètres et gérer les exceptions
return value == (m_pObject->*Get)();
}
// Surcharger l'accès au membres pour accèder au membres de l'objet de la propriété
// et non pas l'instance de la classe property.
ValueType *operator->()
{
return (m_pObject->*Get)();
}
};
////////////////////////////////////////////////////////////////////////////////
// Juste pour tester Intellisense pour l'affichage de la liste des membres d'une classe
// avec l'opérateur surchargé "->" de la classe property
class Redirection
{
public :
int i;
Redirection()
{
i = (int)this;
}
};
////////////////////////////////////////////////////////////////////////////////
// Implémentation des propriétés dans une classe
class Test
{
public :
// Constructeur par défaut
Test()
{
// Initialiser la valeur de la propriété Count
m_Count = 0;
// Préparer les paramètres de fonctionnement de la propriété Count en lecture/écriture
Count.Setup(this, &Test::GetCount, &Test::SetCount);
// Préparer les paramètres de fonctionnement de la propriété Redirectional en lecture seule
Redirectional.Setup(this, &Test::GetRedirection, NULL);
}
Test(int init)
{
m_Count = init;
// Préparer les paramètres de fonctionnement de la propriété Count en lecture/écriture
Count.Setup(this, &Test::GetCount, &Test::SetCount);
// Préparer les paramètres de fonctionnement de la propriété Redirectional en lecture seule
Redirectional.Setup(this, &Test::GetRedirection, NULL);
}
// Property setter de la propriété Count
void SetCount(int value)
{
printf("SetCount called\n");
m_Count = value;
}
// Property getter de la propriété Count
int GetCount(void)
{
printf("GetCount called\n");
return m_Count;
}
// Property getter de la propriété Redirectional
Redirection GetRedirection(void)
{
return this->m_redir;
}
public :
// Déclaration de la propriété Count
property<Test, int> Count;
// Déclaration de la propriété Redirectional
property<Test, Redirection> Redirectional;
private :
// Variable contenant la valeur de la propriété Count
int m_Count;
// Object de la propriété Redirectional
Redirection m_redir;
};
////////////////////////////////////////////////////////////////////////////////
// Programme principal
// Quelques testes...
int main(void)
{
try {
Test test;
test.Count = 11;
int i = test.Count;
Test *pTest = new Test();
pTest->Count = 2;
printf("%d + %d = %d\n", (int)pTest->Count, (int)test.Count, pTest->Count + test.Count);
pTest->Count = test.Count;
printf("%d + %d = %d\n", (int)pTest->Count, (int)test.Count, pTest->Count + test.Count);
Redirection redir;
pTest->Redirectional = redir; // Affectation d'une propriété en lecture seule
delete pTest;
} catch (char *message) {
printf("Exception levée!\n\t%s\n", message);
} catch (...) {
printf("Exception non gérée levée!..");
}
while(true);
} |
Partager