[英]C++ getter/setter paradigm
我最近遇到了这个课程,并对如何实施吸气剂和制定者感到惊讶。
我以前没有碰到这个,并欢迎一些第二意见。
你认为这是一个很好的范例吗? 是坏事吗? 这是邪恶的吗?
标题:
class Tool
{
public:
Tool();
virtual ~Tool();
bool setName(const std::string &name);
bool getName(std::string &name) const;
void clearName();
private:
std::string m_name;
bool m_nameSet;
};
cpp文件:
#include "Tool.h"
Tool::Tool()
: m_name("")
, m_nameSet(false)
{
}
Tool::~Tool()
{
}
bool Tool::setName(const std::string &name)
{
m_name = name;
m_nameSet = true;
return (m_nameSet);
}
bool Tool::getName(std::string &name) const
{
bool success = false;
if (m_nameSet)
{
name = m_name;
success = true;
}
return (success);
}
您选择getter的方式并不受欢迎,程序员更喜欢从getter return
数据
std::string getName() const;
为什么应该在getter上重新检查之前设置或具有初始数据的项目? 如果要验证数据,请在setter上验证。
但是如果你坚持要将值返回为“之前设置的名称”,你可以通过bool isNameSet() const;
写出第三种方法bool isNameSet() const;
这看起来很像C,通常返回状态代码以查看函数是否失败。
然后还有更好的方法来验证名称是否设置。 一个可能是对我使用boost :: optional这是一个更好的方法来声明可能不会始终设置名称的意图。
然而,我想知道通过只有一个构造函数将std :: string作为参数来确保名称始终设置并不是更好。
class Tool
{
public:
//Constructor already does the right thing
Tool() = default;
virtual ~Tool();
//Use void or return the modified class, akin to operators
void setName(const std::string& name)
{
m_name = name;
}
//Alternatively
Tool& setName(const std::string &name)
{
m_name = name;
return *this;
}
//Return const reference to the value if possible, avoids copying if not needed
//This will fail at run time if name is not set
//Maybe throw an exception if that is preferred
const std::string& getName() const
{
return *m_name;
//Or
if(m_name) return *m_name;
else throw some_exception;
}
//Or return the optional, then calling code can check if name where set or not
const boost::optional<std::string>& getName() const
{
return m_name;
}
void clearName()
{
m_name = boost::optional<std::string>();
}
private:
boost::optional<std::string> m_name;
};
我不会称之为范式 。 这似乎是架构的解决方案,其中一个字段可能处于未指定的状态(为什么不呢?有时它是一个理智的要求)。 虽然,我不太喜欢这个解决方案,因为getter应该返回值(对称,setter应该设置它),并且约定通常需要特定的原型:
Type GetValue();
SetValue (const Type & newValue);
or
SetValue (Type & newValue);
or
SetValue (Type newValue);
您应根据情况选择三个安装者中的一个,通常第一个或第二个适合。
如果一个领域可能处于未指定的状态,我会选择另一种方法,正如M M.在他的答案中建议的那样,我将自由提供一个例子:
class C
{
private:
int field;
bool fieldSet;
public:
C()
{
field = 0;
fieldSet = false;
}
bool IsFieldSet()
{
return fieldSet;
}
int GetField()
{
if (!fieldSet)
throw std::exception("Attempt to use unset field!");
return field;
}
void SetField(const int newValue)
{
field = newValue;
fieldSet = true;
}
};
但请注意,我不会这样称之为实施getter evil 。 使用它可能会让人感到不舒服。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.