C++ 能否实现类似 Delphi 的 Property 给属性赋值自动出发写属性函数?

<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, 不要说别人是怪人, 要不没人会帮助你的, 哈哈哈哈

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应该是可以做到的

实現自带pub/sub机制的对象只是 MOP 的一種应用,MOP 的作用在于能让用户扩展编程语言的 OOP 系統。比如,manardb 用 MOP 把 persistent object 实現成了 CLOS 的一个类,用通常操作类的界面,而实际上操作的是数据库。

另外这个应該叫 Dataflow programming。Microsoft Excel 中单元格公式的实現用的也是这种的思想。