我喜欢 6502 的答案。它使用的内存更少,而且比我将提出的解决方案更快。只有我的会有一点语法糖。
我希望能够写出这样的东西(使用 PIMPL 成语):
class A {
private:
class FImpl;
FImpl* Impl;
public:
A();
~A();
Property<int> Count;
Property<int> Count2;
Property<UnicodeString> Str;
Property<UnicodeString> Readonly;
};
完整代码来了(我很确定它符合标准):
template <typename value_t>
class IProperty_Forward {
public:
virtual ~IProperty_Forward() {}
virtual const value_t& Read() = 0;
virtual void Set(const value_t& value) = 0;
};
template <typename value_t, typename owner_t, typename getter_t, typename setter_t>
class TProperty_Forwarder: public IProperty_Forward<value_t>
{
private:
owner_t* Owner;
getter_t Getter;
setter_t Setter;
public:
TProperty_Forwarder(owner_t* owner, getter_t& getter, setter_t& setter)
:Owner(owner), Getter(getter), Setter(setter)
{ }
const value_t& Read()
{ return (Owner->*Getter)(); }
void Set(const value_t& value)
{ (Owner->*Setter)(value); }
};
template <typename value_t>
class Property {
private:
IProperty_Forward<value_t>* forward;
public:
Property():forward(NULL) { }
template <typename owner_t, typename getter_t, typename setter_t>
Property(owner_t* owner, getter_t getter, setter_t setter)
{ Init(owner, getter, setter); }
~Property()
{ delete forward; }
template <typename owner_t, typename getter_t, typename setter_t>
void Init(owner_t* owner, getter_t getter, setter_t setter)
{
forward = new TProperty_Forwarder<value_t, owner_t, getter_t, setter_t>(owner, getter, setter);
}
Property& operator=(const value_t& value)
{
forward->Set(value);
return *this;
}
const value_t* operator->()
{ return &forward->Read(); }
const value_t& operator()()
{ return forward->Read(); }
const value_t& operator()(const value_t& value)
{
forward->Set(value);
return forward->Read();
}
operator const value_t&()
{ return forward->Read(); }
};
还有一些实现细节:
class A::FImpl {
public:
FImpl():FCount(0),FCount2(0),FReadonly("Hello") { }
UnicodeString FReadonly;
const UnicodeString& getReadonly()
{ return FReadonly; }
void setReadonly(const UnicodeString& s)
{ }
int FCount;
int getCount()
{ return FCount; }
void setCount(int s)
{ FCount = s; }
int FCount2;
int getCount2()
{ return FCount2; }
void setCount2(int s)
{ FCount2 = s; }
UnicodeString FStr;
const UnicodeString& getStr()
{ return FStr; }
void setStr(const UnicodeString& s)
{ FStr = s; }
};
A::A():Impl(new FImpl)
{
Count.Init(Impl, &FImpl::getCount, &FImpl::setCount);
Count2.Init(Impl, &FImpl::getCount2, &FImpl::setCount2);
Str.Init(Impl, &FImpl::getStr, &FImpl::setStr);
Readonly.Init(Impl, &FImpl::getReadonly, &FImpl::setReadonly);
}
A::~A()
{
delete Impl;
}
我正在为任何想了解 UnicodeString 类的人使用 C++ Builder。
希望它可以帮助其他人试验符合标准的 c++ 属性。
基本机制与 6502 相同,但限制相同。