使用Set/Get-like方法或GetSet组合函数
Use of Set/Get-like Methods or a GetSet combo function
我喜欢在类中使用C#风格的Gets
和Sets
。然后我遇到了以下示例:注意Port类中第二个SetPort
的声明,即
inline uint16_t & SetPort ( ) { return this->port; }
通过使用"与"符号,您可以创建一个既可以用作Set又可以用作Get的函数,如示例代码所示。我的问题是,为什么要这样做,或者反过来说,为什么要?也许我应该叫它:
inline uint16_t & GetSetPort ( ) { return this->port; }
我理解,我想,为什么这样做有效,我只是想知道,除了减少获取/设置的数量之外,是否有人认为这样做有任何实用性?
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <string.h>
#include <netinet/in.h>
using namespace std;
class Port {
public:
Port ( ) { }
Port ( const Port& orig ) { }
virtual ~Port ( ) { }
inline const uint16_t GetPort ( ) { return this->port; }
inline void SetPort ( const uint16_t p_a ) { this->port = p_a; }
inline uint16_t & SetPort ( ) { return this->port; }
protected:
in_port_t port;
};
int main ( int argc, char** argv )
{
Port * p = new Port ( );
p->SetPort ( 32);
cout << " Port value = " << p->GetPort () << endl;
p->SetPort() = 64;
cout << " Port value = " << p->GetPort () << endl;
p->SetPort(p->SetPort() + 32);
cout << " Port value = " << p->GetPort () << endl;
delete p;
return 0;
}
结果
Port value = 32
Port value = 64
Port value = 96
您想问自己的问题是"我为什么要使用setter/getter?"。
原因通常是为了改进封装,以便能够更好地调试代码(您可以非常容易地记录所有集(。您还可以隐藏实现细节(可能有"getter",但它后面不必有任何一个字段(。
我的观点是,如果您试图在编写这些函数时节省击键次数,并且您愿意通过在外部返回对私有变量的可修改引用来打破封装,那么最好使用纯公共字段。然而,如果您能看到getter和setter在未来很有用,那么您一定应该小心地编写它们来封装您的代码。毕竟,它是您正在设计的类的API。
详细说明您返回引用的具体示例,以便用户可以以这种方式设置值。你有点违背了二传手的目的。
- 您不能检查用户提供的值,例如记录一些特殊情况
- 你甚至不知道用户什么时候设置值,因为他可以保存引用以备以后更改
- 如果只有一个方法同时执行get和set,则会完全丢弃对象的常量(不能仅从
const
实例中获取值(
在设计C++类时,我倾向于使用完整的get/set组合。当我处理的只是一个小数据持有者(通常只是一堆分组在一起的字段(时,我倾向于使用struct
并将所有字段公开。
至于C#,在C#中,自动属性是一种很好的语法糖,它几乎不需要任何成本,而且在需要时编写和重写都很简单。但是,请记住,这些不会破坏封装。
如果您有特定范围的可接受值,您仍然可以使用get-set组合函数,而不会危及封装:
#include <limits.h> // For UINT_MAX
class CPort {
public:
CPort ( ) { }
virtual ~CPort ( ) { }
inline const unsigned int Port ( unsigned int port = UINT_MAX )
{
static_assert( UINT_MAX > 65535 ); // Just to make sure.
if ( port <= 65535 )
m_port = port;
return this->m_port;
}
protected:
unsigned int m_port = UINT_MAX;
};
而非使用:
int main ( int argc, char** argv )
{
CPort P;
P.Port(80);
unsigned int port = P.Port(); // = UINT_MAX means: Uninitialized
return 0;
}
我不确定我是否喜欢它。
相关文章:
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 可组合的lambda/std::函数与std::可选
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 混合组合和继承的C++问题
- 我需要将多个函数组合为一个函数
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 通过组合不同的类型来创建唯一的id
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 模板元编程:如何将参数包组合成新的参数包
- 检查向量是否具有所有可能的字符组合
- 如何在加密++中将两个源组合成新的源
- 根中的组合
- 更改 C++ 中的组合分类变量
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- 组合字符串不适用于 libCurl,C++
- 测试两个类型列表中的所有组合
- 将多个 for 循环组合成单个迭代器
- 如何从组合指数中找到仓位
- 防止组合框被关闭
- 使用Set/Get-like方法或GetSet组合函数