
- вынес все в отдельный класс
- добавил параметризацию, сделав класс шаблонным
- добавил специализацию для типа char*
- ввел в интерфейс класса функтор - указатель на функцию проверки условия, должно присваиваться или нет... в принципе, если условиям r-value не подходит, можно выбрасывать исключение - так вроде правильнее будет...
Вот код:
Код: Выделить всё
#ifndef __PROPERTY_H
#define PROPERTY_H
template <class T>
class PROPERTY
{
private:
T data;
public:
PROPERTY();
PROPERTY(T _data);
operator T() const;
PROPERTY (const PROPERTY&);
PROPERTY& operator=(const PROPERTY& rhs);
~PROPERTY();
bool(*Condition)(T);
};
#endif
#ifndef __PROPERTY_CPP
#define PROPERTY_CPP
// шаблон - конструктор по умолчанию
template <class T>
PROPERTY<T>::PROPERTY():Condition(NULL){/*data(NULL)*/};
// шаблон - конструктор, принимающий параметр типа T
template <class T>
PROPERTY<T>::PROPERTY(T _data):Condition(NULL){data=_data;}
// шаблон - операция преобразования
template <class T>
PROPERTY<T>::operator T() const
{return data;}
// шаблон - операция присваивания
template <class T>
PROPERTY<T>& PROPERTY<T>::operator=(const PROPERTY<T>& rhs)
{
if(this==&rhs) return *this;
if(Condition==NULL)
{
data=rhs.data;
}
else
{
if(Condition(rhs.data)) data=rhs.data;
}
return *this;
}
// шаблон - конструктор копирования
template <class T>
PROPERTY<T>::PROPERTY(const PROPERTY<T>&):Condition(NULL){};
// шаблон - деструктор
template <class T>
PROPERTY<T>::~PROPERTY(){}
// ********** Специализация для char * **********
// char* - конструктор по умочанию
PROPERTY<char*>::PROPERTY():Condition(NULL)
{
data=new char[1]; data[0]='\0';
}
// char* - конструктор, принимающий строку
PROPERTY<char*>::PROPERTY(char* _data):Condition(NULL)
{
int tmp=strlen(_data);
data=new char[tmp+1];
strcpy(data, _data);
data[tmp]='\0';
}
// char* - операция присваивания
PROPERTY<char*>& PROPERTY<char*>::operator=(const PROPERTY<char*>& rhs)
{
if(this==&rhs) return *this;
if(Condition==NULL)
{
delete data;
int tmp=strlen(rhs.data);
data=new char[tmp+1];
strcpy(data,rhs.data);
data[tmp]='\0';
}
else
{
if(Condition(rhs.data))
{
delete data;
int tmp=strlen(rhs.data);
data=new char[tmp+1];
strcpy(data,rhs.data);
data[tmp]='\0';
}
}
return *this;
}
// char* - деструктор
PROPERTY<char*>:: ~PROPERTY()
{
delete data;
}
// char* - конструктор копирования
PROPERTY<char*>::PROPERTY(const PROPERTY<char*>& rhs):Condition(NULL)
{
data=NULL;
operator=(rhs);
}
#endif
Юзается примерно так:
Код: Выделить всё
// Определяем св-во x - работает как целочисленная переменная
PROPERTY<int> x;
// Определяем функцию, накладывающую условие на присваиваемое значение,
// в данном случае оно должно быть в диапазоне [-10;10]
bool f(int arg)
{
if(arg<-10 || arg >10)
{
cout <<"\nRange error!\n";
return false;
}
else
return true;
}
// Устанавливаем это условие на наше св-во x
x.Condition=f;
x=5; // присвоится
x=-5; // присвоится
x=14; // не присвоится