请教高手关于 operator () 操作符?
我想实现一个类似于 C# 的属性,属性自身是没问题的。Int 类自身也没问题,但如果采用模板的方式调用的话会存在问题。我觉得问题的具体细节也许详细描述了,代码中有注明。恳请高手帮忙看看!!!
class Int
{
protected:
int Value;
public:
Int();
Int(const int &value);
Int& operator= (const int &value);
operator int const () const;
};
Int::Int()
{
}
Int::Int( const int &value )
{
Value = value;
}
Int& Int::operator = (const int &value)
{
Value = value;
return *this;
}
Int::operator int const () const
{
return Value;
}
int _tmain(int argc, _TCHAR* argv[])
{
// Int 隐式转换为 int
Int n1 = 1;
int n2 = n1;
property<Int> Width;
Width = 10;
// 此处不支持隐式转换,为什么,该如何处理?
int k = Width;
return 0;
}
[解决办法]
Width是Property<Int>类型,不是Int类型,所以如果int k = Width;编译通过,首先要支持Property<Int>到Int类型的转化,然后才是Int类型到int类型的转化。
[解决办法]
1、给property<Int>定义个int的类型转换
2、用一个函数,比如getint() 返回int值,int k = Width.getint();
两种方法选一个。
个人觉得,隐式(1个参数的构造函数)和显式类型转换(operator type),能少用尽量少用。很容易发生在比较的时候变成赋值,错误隐蔽,代码多的话,查找错误的难度增加。用一个明确意义的函数返回转换的值更不容易出错。
[解决办法]
vc 扩展
// declspec_property.cpp
struct S {
int i;
void putprop(int j) {
i = j;
}
int getprop() {
return i;
}
__declspec(property(get = getprop, put = putprop)) int the_prop;
};
int main() {
S s;
s.the_prop = 5;
return s.the_prop;
}
[解决办法]
说实话还是没看明白你到底要干什么。我猜你好像是要写一个 property 类,能够自动管理其他类,替其他类实现赋值和类型转换的功能,间接调用被管理类的 SetValue/GetValue 函数。如果是这样的话,下面的实现就行。
template <typename DependencyObject>
struct property
{
private:
DependencyObject* Object;
using type = decltype(Object->GetValue());
public:
property (DependencyObject*const object) : Object(object) { }
void operator = (const type& Value)
{
Object->SetValue(Value);
}
operator type const () const
{
return Object->GetValue();
}
};
class Int
{
protected:
int Value;
public:
Int() { }
Int(const int &value) : Value(value) { }
void SetValue (int const& x)
{
Value = x;
}
int GetValue () const
{
return Value;
}
};
int main ()
{
Int a;
property<Int> Width(&a);
Width = 10;
int k = Width;
std::cout << k << std::endl;
}
[解决办法]
#include <iostream>
template <typename DependencyObject>
struct property
{
private:
DependencyObject Object;
public:
property() {}
//property() = default; //this is a better choice,1 : easier to read, 2 : able to make your class "trivial"
property (DependencyObject const &object) : Object(object) { }
void operator=(typename DependencyObject::value_type const &Value)
{
Object.SetValue(Value);
}
void operator=(DependencyObject const &Value)
{
Object = Value;
}
operator typename DependencyObject::value_type const () const
{
return Object.GetValue();
}
};
class Int
{
protected:
int Value;
public:
typedef int value_type;//if compiler support, I would use decltype in property class rather using typedef
Int() {}
Int(const int &value) : Value(value) { }
void SetValue (int const& x)
{
Value = x;
}
int GetValue () const
{
return Value;
}
};
int main()
{
property<Int> a(1000);
std::cout << a << std::endl;
a = 10;
std::cout << a << std::endl;
Int b(100);
a = b;
std::cout << a << std::endl;
return 0;
}