除了具有未分配值(如@code707的答案中所述)之外,您还可以做一些事情。
相同方法,用户可以使用未初始化的类 - 缓解措施
所有这些都是基于存储布尔值,如果用户正确调用set,则可以使用。
使用您的get / set封装来检查是否已设置:
class example {
private:
Color color;
bool isColourSet = false;
public:
Color get_color() const;
void set_color(Color newCol) {
color = newCol;
isColourSet = true;
}
...
然后您可以根据需要以不同的方式使用此布尔值:
抛出异常
Color get_color() const {
if (!isColourSet) throw some_exception; // It wasnt Set!! Throw
return color;
}
这种方式可以避免多余的枚举元素,同时通过抛出异常来防止返回未定义的值。
返回错误代码
如果你不想抛出异常,可以传递一个返回参数并返回一个错误码:
ErrInt get_colour(Colour &out) const {
if (!isColourSet) return STANDARD_ERROR_VAL;
out = color;
return STANDARD_SUCCESS_VALUE;
}
这与枚举中的“坏值”(Bad Value)概念非常相似。
使用std::optional
自以来,您还可以使用一种新的方法std::optional
,其中您可以选择性地返回(而不是引发异常或返回错误值)。
class example {
public:
std::optional<Color> get_colour() {
return color;
}
void set_color(Color newColor) {
color = newColor;
}
private:
std::optional<Color> color;
}
然后用户可以像这样使用它:
auto myColor = myExample.get_colour();
if (myColour) { // Here you can check the optional
myColour.get() // Do something with colour.
...
新的方法,用户无法将类设置为错误状态 - 重新设计
与设置一个值并且必须检查它是否正确相比,也许您可以设计这个类,使其永远不会处于无效状态。让我们看看如何做到这一点:
1. 类型安全
我们不希望用户能够设置我们不知道的任意颜色值。在当前实现中,enum
将是可以使用任何 int
值设置的类型!当某人执行 set_color(538)
时,这意味着什么?我们可以通过 c++11 的 enum class
来解决这个问题:
enum class Color {
RED,
BLUE
}
set_color(523);
set_color(Color::Red);
2个构造函数参数
我们可以通过提供一个只需要颜色参数的构造函数来强制用户选择初始颜色:
class example {
public:
example(Color startColor) : color(startColor) {}
...
private:
Color c;
}
这意味着用户在创建类时必须指定一个初始颜色。现在,如果用户想要更改颜色,我们可以添加set函数:
void change_color(Color newColor) {
color = newColor;
}
3 结论
现在您已经拥有了一个类,用户永远不会陷入无效的情况。我相信这比试图检测用户是否出错创建类要好得多。
c
始终具有有效值,则需要在构造函数中初始化c
。 - Some programmer dudestd :: optional
或将“no_color”添加到枚举中。 - 463035818_is_not_a_number