【发布时间】:2017-09-17 14:32:59
【问题描述】:
我正在编写一个代表按钮的类。这个按钮可能有也可能没有各种属性,比如上面写的文本、快捷方式、纹理或平面颜色填充。因此,例如,如果此按钮没有任何纹理集,则跳过纹理绘制过程。
我的第一个解决方案是使用虚构的默认值,表示给定属性未使用(如果颜色的 alpha 值为 0,则将跳过颜色填充绘图等)。
我的其他选择是使用新添加的 std::optional ,这样使用起来会更清晰、更简单。
这里是提到的两个例子:
class Button {
void draw() {
if (fill)
drawRectangle(*fill);
if (sprite)
drawSprite(*sprite);
if (font)
drawText(name, *font);
}
std::optional<std::string> font;
std::optional<std::string> sprite;
std::optional<Color> fill;
}
class Button {
void draw() {
if (fill.alpha != 0)
drawRectangle(fill);
if (sprite != "")
drawSprite(sprite);
if (font != "")
drawText(name, font);
}
std::string font;
std::string sprite;
Color fill;
}
在这种情况下,使用 std::optional 的优点和缺点是什么?我主要感兴趣的是内存使用和开销差异。
我也应该只是,而不是使用 if 来检查 optional 是否包含值,而是调用 value() 并捕获异常吗?
【问题讨论】:
-
关于使用
.value()并捕获异常而不是检查它是否具有值的问题:这是个坏主意。顾名思义,异常是针对特殊情况的,堆栈展开造成的开销不可忽略。假设有很多按钮,例如不会有颜色,可选的为空根本不是例外情况。 -
我不认为
std::optional<std::string>非常有用,除非空字符串与没有字符串完全不同。 -
std::optional用于函数返回,而不是类成员。这是一件非常浪费的事情。另外,请注意sprite.empty()应该使用sprite == ""。 -
std::optional有内存开销(可能类似于额外的bool) -
我看不出
std::optional有什么优势。此外,请考虑主要的 UI 实现,例如 AWT 和 .NET:空字段实际上是空的,而不是“不存在”。同样,您不会从中获得价值。