Created
July 23, 2009 06:30
-
-
Save alno/152492 to your computer and use it in GitHub Desktop.
Test properties in C++
This file contains hidden or 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
#include <iostream> | |
/** | |
* Класс, предоставляющий общие сервисы для свойств, а также используемый для хранения в классе позиции свойств. | |
*/ | |
template < | |
typename PropertyOwner // Класс владельца | |
> | |
class properties { | |
public: | |
static PropertyOwner * owner( void * property ) { // Получить указатель на владельца по указателю на свойство | |
int aai = (int)&(((PropertyOwner*)0)->__properties); | |
return (PropertyOwner *)((char*)property - aai); | |
} | |
}; | |
/** | |
* Шаблон класса свойства | |
*/ | |
template < | |
typename PropertyOwner, // Класс владельца | |
typename PropertyType, // Тип свойства | |
PropertyType (PropertyOwner::*getter)(), // Геттер | |
void (PropertyOwner::*setter)(PropertyType) > // Сеттер | |
class property { | |
public: | |
/** | |
* Чтение свойства - вызов геттера | |
*/ | |
operator PropertyType() { | |
return (properties<PropertyOwner>::owner( this )->*getter)(); | |
} | |
/** | |
* Запись в свойство - вызов сеттера | |
*/ | |
void operator = ( const PropertyType & value ) { | |
(properties<PropertyOwner>::owner( this )->*setter)( value ); | |
} | |
}; | |
// Макросы для удобного определения свойств ///////// | |
/** | |
* Начать объявления свойств в классе cls | |
*/ | |
#define properties_start(cls) union { properties<cls> __properties; | |
/** | |
* Закончить объявление свойств в классе cls | |
*/ | |
#define properties_end() }; | |
/** | |
* Объявить свойство в классе cls типа type c геттером getter и сеттером setter | |
*/ | |
#define property(cls,type,getter,setter) property<cls,type,&cls::getter,&cls::setter> | |
/* | |
* Ввод и вывод для свойств | |
*/ | |
template < | |
typename PropertyOwner, | |
typename PropertyType, | |
PropertyType (PropertyOwner::*getter)(), | |
void (PropertyOwner::*setter)(PropertyType) > | |
std::ostream & operator << ( std::ostream & os, property<PropertyOwner,PropertyType,getter,setter> prop ) { | |
return os << (PropertyType)prop; | |
} | |
template < | |
typename PropertyOwner, | |
typename PropertyType, | |
PropertyType (PropertyOwner::*getter)(), | |
void (PropertyOwner::*setter)(PropertyType) > | |
std::istream & operator >> ( std::istream & is, property<PropertyOwner,PropertyType,getter,setter> prop ) { | |
PropertyType value; | |
is >> value; | |
prop = value; | |
return is; | |
} | |
class CClass { | |
private: | |
int a_value; | |
/** | |
* Геттер | |
*/ | |
int getA() { | |
return a_value; | |
} | |
/** | |
* Сеттер | |
*/ | |
void setA( int a ) { | |
a_value = a; | |
} | |
public: | |
properties_start( CClass ); // Начало свойств | |
property( CClass, int, getA, setA ) a; // Свойство | |
properties_end(); // Конец свойств | |
}; | |
int main( int argc, char ** argv ) { | |
CClass c; | |
c.a = 145; | |
std::cout << "Class size:" << sizeof( CClass ) << std::endl; | |
std::cout << c.a << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment