Tôi thích câu trả lời của 6502. Nó sử dụng cả bộ nhớ ít hơn và nhanh hơn giải pháp tôi sẽ trình bày. Chỉ có tôi sẽ có một đường cú pháp.
tôi muốn để có thể wite một cái gì đó như thế này (với pImpl thành ngữ):
class A {
private:
class FImpl;
FImpl* Impl;
public:
A();
~A();
Property<int> Count;
Property<int> Count2;
Property<UnicodeString> Str;
Property<UnicodeString> Readonly;
};
Ở đây có mã completet (tôi khá chắc chắn rằng nó là tuân thủ QTI tiêu chuẩn):
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(); }
};
Và một số chi tiết triển khai:
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;
}
Tôi đang sử dụng C++ Builder cho bất kỳ ai thắc mắc về UnicodeS tring class. Hy vọng nó sẽ giúp những người khác để thử nghiệm Tiêu chuẩn phù hợp C++ Thuộc tính. Cơ chế cơ bản giống như 6502, với cùng giới hạn.
Không có từ khóa 'ngầm 'trong C++ 0x. Tôi không thể nhận được liên kết mà bạn đăng mặc dù (nó yêu cầu một tên người dùng/mật khẩu). –
Tôi đã cập nhật liên kết. Có vẻ như không bao giờ được đưa vào thông số C++ 0x. –
$ 0,02 của tôi là rõ ràng nếu bạn đang hướng tới tính di động, chỉ cần tránh xa các phần mở rộng này. Giai đoạn. – sehe