错误 - c取临时地址

时间:2013-02-13 10:00:34

标签: c++

我在下面的代码中遇到错误

void setStyle(const ctlStyleBase* style)
{
  //do something
}

void create(const ctlStyleBase* style = 0)
{
      if(style == 0) setStyle(&ctlStyleGradient());  // error : taking address of temporary
      else setStyle(style);
}

我不认为这是错误的,因为我只在setStyle中使用它,并且在setStyle返回之前它不会被破坏。 有人可以告诉我代码是否有问题吗?

[compiler g ++ 4.7.2]

3 个答案:

答案 0 :(得分:2)

嗯,很难 - 这是一种语言规则,你无法获取临时对象的地址。规则的原因是基本上没有一个好的原因来做到这一点。

在您的示例中,ctlStyleGradient()返回一些ctlStyleBase类型的对象。如果你想在setStyle函数中修改该对象(虽然在这种情况下你不是这样),那么一旦你完成,对象就不再存在,从而使整个修改毫无意义。

是的,您可以设计操作具有可观察到的副作用的代码,但这本身就是非常糟糕的风格。因此,没有深层次的技术理由说明为什么你不能拿一个临时的地址,但语言决定不让你这么做,因为它被认为是不恰当的。

但这似乎不是你想要做的。也许你要做的是让ctlStyleGradient()返回指针本身?或者,如果您只需观察状态并且从不更改状态,请按值或const-reference传递状态。

答案 1 :(得分:0)

问题是你根本无法获取右值表达式的地址。您的ctlStyleGradient按值返回ctlStyleBase,将其复制出函数。这为您提供了一个临时表达式ctlStyleGradient()是一个右值表达式。然后,您无法对此表达式&执行此操作。

如果您不需要修改传递给setStyle的对象,则可以将其更改为const引用:

void setStyle(const ctlStyleBase& style)
{
  //do something
}

if(style == 0) setStyle(ctlStyleGradient());

如果您确实需要修改它,那么您必须获取ctlStyleBase对象的本地副本并按值或引用传递:

void setStyle(ctlStyleBase style)
{
  //do something
}


if(style == 0) {
  ctlStyleBase styleCopy = ctlStyleGradient();
  setStyle(styleCopy);
}

答案 2 :(得分:0)

你可以这样做:

void create(const ctlStyleBase* style = 0)
{
      if(style == 0)
      {
          ctlStyleGradient temp;
          setStyle(&temp);
      }
      else setStyle(style);
}

但是,老实说,我会修改你的代码,所以你不要这样做,将指针传递给像这样的局部变量是有风险的业务。也许改变setStyle调用,以便检查空指针?