这是我写的一个用来模拟.NET属性的类。它似乎做我想要的。然而,不是使用Property1和Property2,我可以写属性并让它弄清楚我想要的两个类中的哪一个?
#include <cstdio>
template <class T>
class Property{
protected:
Property(const Property&p) {}
Property() {}
public:
virtual Property& operator=(const Property& src)=0;
virtual Property& operator=(const T& src)=0;
virtual operator T() const=0;
};
template <class T>
class Property1 : public Property<T> {
T v;
public:
Property1(const Property1&p) {*this=static_cast<T>(p);}
//Property1() { printf("ctor %X\n", this);}
Property1(){}
Property& operator=(const Property& src) { return*this=static_cast<T>(src); }
Property& operator=(const T& src) {
printf("write %X\n", this);
v = src;
return *this;
}
operator T() const {
printf("Read %X\n", this);
return v;
}
};
template <class T>
class Property2 : public Property<T> {
typedef T(*Gfn)();
typedef void(*Sfn)(T);
Gfn gfn;
Sfn sfn;
public:
Property2(const Property2&p) {*this=static_cast<T>(p);}
//Property2() { printf("ctor %X\n", this);}
Property2(Gfn gfn_, Sfn sfn_):gfn(gfn_), sfn(sfn_) {}
Property& operator=(const Property& src) { return*this=static_cast<T>(src); }
Property& operator=(const T& src) {
printf("write %X\n", this);
sfn(src);
return *this;
}
operator T() const {
printf("Read %X\n", this);
return gfn();
}
};
void set(int v) {}
int get() {return 9;}
Property1<int> a, b;
Property2<int> c(get,set), d(get,set);
void fn(Property<int>& v) { v=v=31; }
int main(){
a=b=5;
c=d=11;
a=c=b=d=15;
fn(a);
fn(c);
}
答案 0 :(得分:2)
您可以Property
暂停并操作实施,让Property1
和Property2
成为两个此类实现,并确定通过Property
'创建两个中的哪一个s ctor:
template<typename T>
class PropertyInterface {
public:
virtual ~PropertyInterface() {}
virtual T get() const = 0;
virtual void set(const T&) = 0;
};
template<typename T>
class Property1 : public PropertyInterface<T> {
T v;
public:
T get() { return v; }
void set(const T& value) { v = value; }
};
template<typename T>
class Property2 : public PropertyInterface<T> {
Gfn g;
Sfn s;
public:
Property2(Gfn getter, Sfn setter) : g(getter), s(setter) {}
T get() { return g(); }
void set(const T& v) { set(v); }
};
template<typename T>
class Property {
PropertyInterface<T> impl;
public:
Property() : impl(new Property1()) {}
Property(const T& v) : impl(new Property1()) { impl->set(v); }
Property(Gfn getter, Sfn setter) : impl(new Property2(getter, setter)) {}
Property(const Property& p) : impl(new Property1()) { impl->set(p.impl->get()); }
// ...more ctors...
~Property() { delete impl; }
Property& operator=(const Property&) { impl->set(p.impl->get()); return *this; }
Property& operator=(const T& v) { impl->set(v); return *this; }
operator T() const { return impl->get(); }
};
答案 1 :(得分:0)
这不是工厂应该做的吗?
工厂方法也可以放在属性类中。我更喜欢创建一个额外的工厂类,以明确它是工厂模式的使用。
编辑:添加工厂方法的重载
template <class T>
class Property {
};
template <class T>
class Property1 : public Property<T> {
};
template <class T>
class Property2 : public Property<T> {
public:
typedef T(*Gfn)();
typedef void(*Sfn)(T);
Property2(Gfn, Sfn) {}
};
class PropertyFactory {
public:
template<class T>
static Property<T>* InstanciateProperty() {
return new Property1<T>();
}
template<class T>
static Property<T>* InstanciateProperty(typename Property2<T>::Gfn gfn, typename Property2<T>::Sfn sfn) {
return new Property2<T>(gfn, sfn);
}
};
void set(int){}
int get() { return 0; }
int main(int argc, char *argv[])
{
Property<int>* prop(PropertyFactory::InstanciateProperty<int>());
Property<int>* prop1(PropertyFactory::InstanciateProperty<int>(&get, &set));
delete prop;
delete prop1;
return 0;
}