V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
ligiggy
V2EX  ›  程序员

半路出家 C++, 求知道参数“读/写”的标准

  •  
  •   ligiggy · 2021-07-12 09:54:22 +08:00 · 3658 次点击
    这是一个创建于 1260 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前写了几年 C#,属性搭配字段用起来是真的太香了。

    但是现在用 C++,基本上单个参数的读写都要写 getter/setter 函数。

    但是当有属于某个 class 的 20 多个参数需要读写的时候,就感觉单纯的 getter/setter 有点麻烦了。

    我目前的做法是将 20 多个参数放到集合中,采用枚举的方式来读写这个集合中的某一个 index 。

    但是我看到我的同事也有用 struct 的方式来直接读 /写。

    所以想问下大家觉得应该怎么来,或者有没有类似的标准文档、书籍。

    33 条回复    2021-07-13 12:38:51 +08:00
    dynastysea
        1
    dynastysea  
       2021-07-12 10:23:25 +08:00   ❤️ 4
    十年 c/c++工作经验,呆过几家公司,从来没见过哪个写 c++还搞 getter 、setter 函数,你们的技术老大是从 java 转型到 c++的吗。一般来说直接修改就可以了,参数多的话适当封装下 struct 传引用或者指针
    chesterzzy
        2
    chesterzzy  
       2021-07-12 10:27:35 +08:00   ❤️ 1
    个人而言,如果代码量少,或者和别的代码耦合少,还能为了强迫症写一些 getter,setter

    如果代码复杂,耦合强了,就直接 public 里写一下了,毕竟为了稳定不出奇怪的问题,也是一种权衡吧,等实在受不了了,就梭哈重构。
    ligiggy
        3
    ligiggy  
    OP
       2021-07-12 10:34:58 +08:00
    @dynastysea 很多开源库源码都有 get/set 的啊
    ligiggy
        4
    ligiggy  
    OP
       2021-07-12 10:35:49 +08:00
    @chesterzzy 20 多个参数的话,得写 40 多个呢,着实有点难受
    dynastysea
        5
    dynastysea  
       2021-07-12 10:37:52 +08:00
    @chesterzzy 举几个学习下,平时重点还是在 C,无论是内核,redis 这类都没看到过
    chesterzzy
        6
    chesterzzy  
       2021-07-12 10:47:38 +08:00
    @ligiggy 基本就按照一楼的说法来就行。要不给参数们再分分组啥的,反正逻辑上整洁就好点了。


    @dynastysea @错人了?
    ligiggy
        7
    ligiggy  
    OP
       2021-07-12 10:53:04 +08:00
    @dynastysea 额,不一定是开源的哈。我看到的 MFC 和 Qt 这种 gui 的库就有很多 get/set
    Hallelu
        8
    Hallelu  
       2021-07-12 10:55:31 +08:00
    如果框架,开源库之类的大多数会写 get/set,但公司的业务场景基本上都是直接 public,很少会写 get/set,除非一些涉及到多线程、安全之类的问题。
    newmlp
        9
    newmlp  
       2021-07-12 11:09:24 +08:00
    如果仅仅时赋值取值的话,直接 public 不就行了,
    aneostart173
        10
    aneostart173  
       2021-07-12 11:12:25 +08:00
    要么用 friend,要么 public 。少数情况下会写 getter,而且不是所有参数,从来不写 setter,写 setter 属于脱裤子放屁。
    ipwx
        11
    ipwx  
       2021-07-12 11:13:53 +08:00
    1. 你的方法(集合 + index )会造成及其难以维护的代码,强烈反对。
    2. getter/setter 是可选的。有时候简单的对象 struct + 裸属性就行了。毕竟如果你一个对象整体 const 了,它的属性就是不可变的。
    3. 参考第二条,有时候你可以 rely on const,比如 std::vector<const T>。
    4. 实在需要的时候,找一些工具帮你产生这些代码会比较好。
    3dwelcome
        12
    3dwelcome  
       2021-07-12 11:20:19 +08:00
    C#的 get/set 是很正常的事情,大部分 MVVM 也推荐用 get/set 封装,这样中间的 ViewModel 层就能多做一些半自动化处理。

    但问题是 C++专业写界面毕竟少,大部分都写一些快速算法,写 get/set 就是单纯的去隐藏 private 属性。
    littlewing
        13
    littlewing  
       2021-07-12 11:21:42 +08:00
    "参数"? 你说的是 成员变量吧
    建议用 struct 或者 全 public
    ruiyi1994
        14
    ruiyi1994  
       2021-07-12 11:54:36 +08:00
    nicebird
        15
    nicebird  
       2021-07-12 11:59:12 +08:00
    - 直接读写
    - class 参数 20 多个,还需要外部去读写,说明设计优点问题,一般不要超过 5-8 个参数,重新组合一下。
    agagega
        16
    agagega  
       2021-07-12 12:04:11 +08:00 via iPhone
    C++有 Hack 可以达到类似 getter setter 的效果,但建议还是看情况而定。set 的时候不做其他事情就直接 public 吧
    danc
        17
    danc  
       2021-07-12 12:12:57 +08:00   ❤️ 2
    你是写业务,又不是写库。写库时用 getter/setter 更多是为了保持 api 稳定,比如我现在写了一库,我并没有把内部变量直接 public 让你访问,而是用 getter/setter 。等有一天,我改变了内部实现,或者发现了一个比我实现更好的 ,我直接套娃它。但我已经给你的 api,是始终不变的,即使 deprecated,即使编译时给你个 warn 。但你写业务嘛,三天两头改,没准哪天就重构,就别做这些无用功了。
    pipilu
        18
    pipilu  
       2021-07-12 12:24:24 +08:00
    用工具生成 getter 和 setter,要么就 struct
    dynastysea
        19
    dynastysea  
       2021-07-12 14:07:34 +08:00
    @ligiggy 噢噢,明白,你这是前端 C++,我一直搞的是后端,MFC 、QT 这些应该是有可能的
    darknoll
        20
    darknoll  
       2021-07-12 14:39:03 +08:00
    我就 public,还 get/set,多麻烦
    clockwise9
        21
    clockwise9  
       2021-07-12 15:11:07 +08:00
    Protobuf (或类似物)考虑一下?
    anytk
        22
    anytk  
       2021-07-12 15:20:47 +08:00   ❤️ 1
    xcstream
        23
    xcstream  
       2021-07-12 18:21:50 +08:00
    c++是多模式的,没有统一标准
    GeruzoniAnsasu
        24
    GeruzoniAnsasu  
       2021-07-12 19:06:39 +08:00
    - 同时需要 getter 和 setter 的成员为什么不直接暴露成 public 就好?
    - 多达几十个的参数全都需要一个个 set ?而不是传递统一结构或者从中间表示(比如 map ) parse ?
    - 这些成员能不能重新组合?这样可以用 initializer_list 来构造组合成员,也是一种批量 set 的方式

    - 你选了最不可取的一种方式,无法组合赋值、调试的时候调试器会不认识你的枚举、慢、难维护、ABI 极不稳定(万一枚举中间插了一行所有的 set 都会出错),既不解决 setter 本来解决的问题,也没有解决 get/set 很麻烦的问题
    786375312123
        25
    786375312123  
       2021-07-12 20:19:45 +08:00
    "但是现在用 C++,基本上单个参数的读写都要写 getter/setter 函数。"

    如果每个参数都需要暴露的话,直接弄 struct 就行了
    noroot
        26
    noroot  
       2021-07-12 20:34:07 +08:00
    getter/setter 主要用来做数据封装和有效性保护的,如果没这些需求可以直接操作。
    iceheart
        27
    iceheart  
       2021-07-12 20:56:25 +08:00 via Android
    Java 里有标准,C++里没这标准。公司有标准就按公司的来,没有就自己定
    edimetia3d
        28
    edimetia3d  
       2021-07-12 21:49:50 +08:00
    对外 public 的 interface 肯定是用 getter setter 的,理由非常多,同时建议搭配 pimpl

    不对外的部分,还是怎么方便怎么写吧,getter/setter 太麻烦了
    openmm
        29
    openmm  
       2021-07-12 23:12:08 +08:00
    确实 如果不是作为很独立的模块或者写成库调用 不用 getter/setter 没毛病
    mingl0280
        30
    mingl0280  
       2021-07-13 04:50:31 +08:00 via Android
    自己搓俩宏生成 getter/setter 呗,C++没这标准。
    ligiggy
        31
    ligiggy  
    OP
       2021-07-13 09:59:48 +08:00
    @GeruzoniAnsasu 我这种方式不使用 getter/setter,插了一个枚举,唯一的问题就是从配置文件中读出来的时候,需要重新设置。但是因为有枚举值,实际上 index 传的就是枚举,在可读性上,我觉得其实是没有问题的。
    7075
        32
    7075  
       2021-07-13 11:02:42 +08:00   ❤️ 1
    getter/setter 是更高层抽象出来的具体的工程实践特性(目标是提升工程代码质量),非语言特性。
    andyhuzhill
        33
    andyhuzhill  
       2021-07-13 12:38:51 +08:00   ❤️ 1
    用 QtCreator 是可以直接快捷键生成 getter setter 的
    其实 Eclipse 也有快捷键 多熟悉一下你用的 IDE 的快捷键吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1723 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 16:31 · PVG 00:31 · LAX 08:31 · JFK 11:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.