guo
2018 年9 月 12 日 04:06
1
<C++能否实现类似Delphi的Property给属性赋值自动出发写属性函数?>
搜了一圈,要么是定义setXXX()/getXXX函数这种所谓的Getter/Setter, 太Low,实际上也没啥意义.
要么是一大堆Template弯弯绕,复杂无比,得不偿失.
作为面向对象的语言,Delphi在一百年前就已经实现的"属性"概念,在c++貌似并不存在.
有没有哪位怪人提点一下...
ps:
我原来的标题是:"C++能否实现类似Delphi的Property给属性赋值自动出发写属性函数"
系统提示:"标题似乎不清楚,这是一个完整的句子?" 是什么鬼?
系统不鼓励把标题写清楚吗?
C++不是一个高级语言,大部分东西都是手动的,所以get/set或者template都是很c++的解决方案……Delphi的这种“神奇”的功能不是C++推崇的。感觉有点类似于python里的property,但实际上也就是get/set
Qt 用 C++ 实现了属性机制: http://doc.qt.io/qt-5/properties.html , 可以参考一下.
BTW, 不要说别人是怪人, 要不没人会帮助你的, 哈哈哈哈
guo
2018 年9 月 12 日 04:32
4
QT 的实现代价更大.
Property对于对象来说,是个非常自然的概念. 实现对property的getter/setter可以使代码非常优雅和自然.
使用Property可以很容易的在对象内部切换对属性的操作, 如果没什么特别要求,直接定义成变量,如果需要复杂操作,增加一个setter即可,对外部调用者完全透明.
BTW, 日常使用emacs干活的,在其他人眼里,都是"怪人"....哈哈,并非贬义...
Qt 的属性除了一般用途, 还主要用于和信号的结合, 任何属性变了都会有信号处理.
C++ 其实是一门有很多强大库的工程语言, 语言本身并没有太多现代化的配备, 主要C++的包袱太重了
听 @LdBeth 说了好多次meta-object protocol,一直不懂,看到Qt这文档好像一下明白了:就是一类对象,它们全都自带pub/sub机制。
不懂 C++。
属性写起来确实清爽,但如果改变了可访问性,外部调用也是要改的。
以前写过 C#(.Net 2.0 时代😅),属性是这么定义的:
class Foo {
int Prop1 { get; set }
int Prop2 { get } // Read only
private int prop3;
int Prop3 {
get {
return this.prop3;
}
set {
if (prop3 > 0) {
this.prop3 = value;
}
}
}
}
简单写 get
/set
的叫 Auto-Implemented Property
, 写 get {...}
/ set {...}
的叫做 Manual-Implemented Property
。后者跟写 GetXXX/SetXXX 已经没多大区别了(当然访问的时候是属性名,而不是 GetXXX/SetXXX),只是写在一起没那么凌乱。
我想是不是可以用宏来模拟类似的乞丐版效果。很久没写 C,宏的用法也忘差不多了:
#include <iostream>
using namespace std;
// ----------------------------------------------------------------------
// Auto-Implemented Property
#define APROPERTY_GET(type, var) \
type Get##var() \
{ \
return _##var; \
}
#define APROPERTY_SET(type, var) \
void Set##var(type val) \
{ \
_##var = val; \
}
#define APROPERTY_NULL(type, var)
#define AP_GET() \
APROPERTY_GET
#define AP_SET() \
APROPERTY_SET
#define AP_NULL() \
APROPERTY_NULL
#define APROPERTY(type, var, getter, setter) \
private: \
type _##var; \
public: \
getter(type, var) \
setter(type, var)
// ----------------------------------------------------------------------
// Manual-Implemented Property
#define MPROPERTY(type, var, ...) \
private: \
type _##var; \
public: \
__VA_ARGS__
// ----------------------------------------------------------------------
class Foo {
APROPERTY(int, Var1, AP_GET(), AP_SET())
APROPERTY(int, Var2, AP_GET(), AP_NULL()) // Read only
MPROPERTY(float, Var3,
float GetVar3 () {
return _Var3;
}
void SetVar3 (float val) {
_Var3 = val;
})
};
int main(int argc, char *argv[])
{
Foo foo;
foo.SetVar1(42);
foo.SetVar3(42.195f);
cout << foo.GetVar1() << '\n';
cout << foo.GetVar3();
return 0;
}
MPROPERTY
我希望这样写 MPROPERTY(float, Var3, { return _Var3; }, { _Var3 = val; })
,可惜不能,不像 elisp 可以推迟表达式求值。
强制使用 GetXXX/SetXXX 也是一种透明,如果不介意它难看。
我觉得楼主的意思是 自动区分 obj.field 与 obj.field = expression
这个应该需要语法分析与重写。用clang应该是可以做到的
LdBeth
2018 年9 月 15 日 05:02
12
实現自带pub/sub机制的对象只是 MOP 的一種应用,MOP 的作用在于能让用户扩展编程语言的 OOP 系統。比如,manardb 用 MOP 把 persistent object 实現成了 CLOS 的一个类,用通常操作类的界面,而实际上操作的是数据库。
另外这个应該叫 Dataflow programming 。Microsoft Excel 中单元格公式的实現用的也是这种的思想。