读书人

关于 operator () 操作符

发布时间: 2013-08-16 14:29:57 作者: rapoo

请教高手关于 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;
}


[解决办法]
引用:
这两个的Int大小写是不一样的,下面的int我还特地用粗体标了一下。
property<Int> Width; // 不可以,Int是我自定义类型
property<int> Width; // 可以,int是C++内置类型。

您的代码只是完成了赋值操作,并且可以返回值。因为我上面的代码只是为了说明问题,所以就把一些不相干的地方去掉了。
实际的代码中是这样的:

// 属性定义
#define Property(DependencyProperty, Type)\
struct\
{\
private:\
DependencyObject *Object;\
\
public:\
void Initialize(DependencyObject *object)\
{\
Object = object;\
}\
void operator = (const Type &Value)\
{\
Object->SetValue(DependencyProperty, Value);\
}\
operator Type const () const\
{\
return Object->GetValue(DependencyProperty);\
}\
}

当然,我这边用的是宏,最终用宏或者模板这倒不是重点。

说实话还是没看明白你到底要干什么。我猜你好像是要写一个 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;
}



读书人网 >C++

热点推荐