来自Java / C#背景,我正在尝试实现一个null安全检查对象。以下代码尝试检查对象上是否确实存在颜色。如果有,我希望能够做一些事情(例如在形状上绘制颜色)。我希望能够将此颜色设置回null(noneColor),以防止为对象着色。
我不想将此颜色设置为具有指针,因为有必要在每个设置方法和解构函数上将其删除。这是一个坏主意吗?
码:
static const Color& noneColor = Color();
static bool isNoneColor(const Color& color) {
return std::addressof(noneColor) == std::addressof(color);
}
MyShape:MyShape() {
this->color = noneColor; // this->color is an object of Color
}
void MyShape::setColor(const Color& newColor)
{
this->color= newColor;
}
void MyShape::draw()
{
if(!isNoneColor(this->color))
// Color shape
}
//different scope/class
void B::setColorForShape()
{
Color color = Color(255,255,255);
a->setColor(color);
// Calling isNoneColor(a->color); should return false;
// After this function ends does variable a->color have undefined behavior?
}
void B::setNoneColorForShape()
{
a->setColor(noneColor);
//Calling isNoneColor(a->color); should return true;
}
方法结束后,使用a-> color调用isNoneColor是否安全?
编辑:
MyShape:color
被宣告有Color& color
。我希望能够在我的对象上设置noneColor状态MyShape
。使用简单的Color对象,我不知道该颜色是否为“空” /空状态。
鉴于
MyShape :: color被声明为Color&
...代码有点问题。
关于C ++引用的了解是,您不能重新使用它们-也就是说,与C ++指针不同,一旦声明了C ++引用,它将始终引用被声明为引用的对象,并且无法重新引用-指向引用其他对象。(顺便说一句,这也是为什么您不允许声明未绑定的引用的原因,例如,MyColor & c;
将不会编译,因为它将无用)
由此可见,这段代码实际上是做什么的:
void MyShape::setColor(const Color& newColor)
{
this->color= newColor;
}
被的内容覆盖(无论所引用的Color
对象this->color
)的内容newColor
。它根本不会改变引用本身。而是通过引用来编写。(请记住,引用被定义为“某物的别名”,因此无论您在何处指定引用,该程序的行为都将如同您在此处指定了对象引用的引用一样)。
要回答名义上的问题:持有C ++引用并不能保证引用所引用的对象不会被破坏。很有可能删除(或销毁)被引用的项目,并以“悬挂引用”结束,如果您尝试使用它,它将调用未定义行为。
作为一般建议,如果您希望有一个保护值来表示“无颜色”,最好的方法是将保护值表示为一个实际的颜色对象(例如Color(0,0,0,0)
,如果您的Color
班级有一个alpha值,则可以工作)-通道,因为alpha = 0的任何颜色都是透明的,因此是无颜色的)。这样,就无需玩带有指针或引用的游戏来尝试表示该信息。如果由于某种原因无法执行此操作,请查看std :: optional作为表示“值或无”的一种方式。
最后一点,当指针指向堆栈对象或成员对象时,使用指针并不意味着必须使用new
和delete
-指针同样工作良好(并且可能同样严重地摔倒自己)。也就是说,指针非常强大,而且也很危险,因此我不建议您将它们用于此目的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句