【小设计】基于宏实现的C++ 可复用setter 和getter设计

前言

  • 最近在开发unity游戏的时候,面对庞大复杂的不同类之间进行数据交换和调用,我们必须做好类数据的信息管理,往往我希望暴露给其他类越少越好,这时候我就利用了C#的一个语言特性
cs 复制代码
public PlayerStateMachine stateMachine{get;private set;}
  • 熟悉的朋友不应该陌生,在面向对象编程中,settergetter 是用于访问和修改私有成员变量的方法。它们通常用于封装(encapsulation),这是一种将数据和行为组合在一个单元(即类)中,并仅通过公共接口访问和操作这些成员的技术。
  • 然后在C++中,却没有提供这个内置的语言特性,本期我来分享一个可复用的C++ 可复用setter 和getter设计

C++ 普通getter和setter的实现

  • 在正常情况下,setter和getter在C++没有原生态支持的情况下,我们可以仿照其设计思路,完成下述代码。
cpp 复制代码
class Context {
private:
    int value;

public:
    void setValue(const int&v) { value = v; }
    int getValue() const { return value; }
};
  • 上述代码看起来没有任何问题,在private作用域下,用户需要访问value必须通过getValue(),如果我们只希望用户能得到数值而不允许用户修改,我们只需要保留getValue()函数即可
  • 然后上述代码存在一个潜在的问题,当一个类中存在多个像这样维护的变量,那我岂不是要定义一堆新的getter函数
cpp 复制代码
public:
    int getValue1() const { return value1; }
    int getValue2() const { return value2; }
    int getValue3() const { return value3; }
    int getValue4() const { return value4; }
    int getValue5() const { return value5; }

宏实现

  • 这里使用宏 PUBLIC_GETTER_PRIVATE_SETTER 来定义一个带有公共获取器和私有设置器的成员变量。
cpp 复制代码
#define PUBLIC_GETTER_PRIVATE_SETTER(memberType, memberName) \
private: \
    memberType memberName; \
public: \
    memberType get##memberName() const { return memberName; } \
    //void set##memberName(memberType val) { memberName = val; }
    
#include <iostream>
class Context {
public:
    Context() :value1(10) {}

	PUBLIC_GETTER_PRIVATE_SETTER(int, value1) ;
};

int main() {
    Context context;
    std::cout << context.getvalue1() << std::endl;
    return 0;
}
  • 指针测试,我们替换为其他类
cpp 复制代码
#define PUBLIC_GETTER_PRIVATE_SETTER(memberType, memberName) \
private: \
    memberType memberName; \
public: \
    memberType get##memberName() const { return memberName; } \
    //void set##memberName(memberType val) { memberName = val; }
class A {

PUBLIC_GETTER_PRIVATE_SETTER(int, value);
public:
    A() :value(10) {}
};
#include <iostream>
class Context {
public:
    Context() :a(new A()) {}

PUBLIC_GETTER_PRIVATE_SETTER(A*, a) ;
};

int main() {
    Context context;
    std::cout << context.geta()->getvalue()<< std::endl;
    //context.geta()->value = 20;//无法访问
    return 0;
}

小结

  • 题外话:C++适当用宏!适当用宏!适当用宏!
  • 如有错误,欢迎指出!
相关推荐
我好喜欢你~5 小时前
C#---StopWatch类
开发语言·c#
快乐的划水a7 小时前
组合模式及优化
c++·设计模式·组合模式
星星火柴9368 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑9 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
一阵没来由的风9 小时前
拒绝造轮子(C#篇)ZLG CAN卡驱动封装应用
c#·can·封装·zlg·基础封装·轮子
阿巴~阿巴~11 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
旺小仔.12 小时前
双指针和codetop复习
数据结构·c++·算法
jingfeng51412 小时前
C++ STL-string类底层实现
前端·c++·算法
郝学胜-神的一滴12 小时前
基于C++的词法分析器:使用正则表达式的实现
开发语言·c++·程序人生·正则表达式·stl
努力努力再努力wz14 小时前
【c++深入系列】:万字详解模版(下)
java·c++·redis