链接方法和临时变量,请澄清

发布于 2024-09-13 18:19:19 字数 873 浏览 7 评论 0原文

大家好!

我有一个类,它接收指向“圆”的指针(例如),然后通过一些“链接”方法调整其属性。像这样的事情:

class CCircleSetter
{
public:
   explicit CCircleSetter( CCirclePtr circle ) : m_circle(circle)
   {
   }

   CCircleSetter & Radius( int radius )
   {
       if (m_circle) m_circle->SetAttribute( "radius", radius );
       return *this;
   }
   CCircleSetter & Center( CPoint center )
   {
       if (m_circle) m_circle->SetAttribute( "center", center );
       return *this;
   }

   operator bool() const
   {
      return ( m_circle != NULL );
   }

private:
   CCirclePtr m_circle;
};

现在我想知道这段代码是否合法:

if ( CCircleSetter(myCircle).Radius(10).Center(myPoint) ) 
{ ... }

一方面,我认为在“if”表达式内创建的临时对象将一直存在到该表达式的末尾。因此,对“Radius”和“Center”的调用是合法的。但另一方面,使用对临时变量的引用是一种未定义的行为,在我看来,我正在做这种事情 - 使用 (*this),其中“this”是临时变量。这让我有些疑问,所以请澄清。谢谢!

Greetings, everyone!

I have a class that receives a pointer to a "circle" (for example) and then adjusts its attributes via some "chaining" methods. Something like this:

class CCircleSetter
{
public:
   explicit CCircleSetter( CCirclePtr circle ) : m_circle(circle)
   {
   }

   CCircleSetter & Radius( int radius )
   {
       if (m_circle) m_circle->SetAttribute( "radius", radius );
       return *this;
   }
   CCircleSetter & Center( CPoint center )
   {
       if (m_circle) m_circle->SetAttribute( "center", center );
       return *this;
   }

   operator bool() const
   {
      return ( m_circle != NULL );
   }

private:
   CCirclePtr m_circle;
};

Now I wonder whether this code is legal or not:

if ( CCircleSetter(myCircle).Radius(10).Center(myPoint) ) 
{ ... }

On the one hand, I think that temporary object, created inside "if" expression, will live until the end of this expression. So, the calls to "Radius" and "Center" are legal. But on the other hand, it is an undefined behavior to use references to temporary variables and it seems to me that I am doing exactly this kind of thing - using (*this), where "this" is a temporary. It gives me some doubts, so, please, clarify. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乖乖兔^ω^ 2024-09-20 18:19:19

不,在这种非常特殊的情况下,这很好,因为在执行整行之后,临时对象将被销毁,但一般来说,保存对临时对象的引用是非常糟糕的。

No, that's fine in this very specific case, because the temporary will be destroyed AFTER the whole line will execute, but in general is very bad to hold references to temporaries.

秋心╮凉 2024-09-20 18:19:19

即使它是临时变量,也不意味着它的所有成员都是临时的。在临时对象的范围内,this 指针和其他成员不是临时的。你的代码完全没问题。现在,如果您执行以下操作:

SomeFunc(&CCircleSetter(myCircle))

这将是对临时变量的引用。

Even if it's a temporary variable, that doesn't mean that all of its members are temporary. Inside the scope of your temp object, the this pointer and other members are not temporary. Your code is completely fine. Now if you did something like:

SomeFunc(&CCircleSetter(myCircle))

this would be a reference to a temp variable.

深海蓝天 2024-09-20 18:19:19

我不认为对临时的引用是未定义的,它只是被禁止的。另外,我相信这只适用于函数参数。 Visual Studio 将允许您在默认警告/错误级别上传递对非常量临时对象的引用,但我知道 gcc 不会。

据我所知,这样做只是被禁止的,这样程序员就不会因为存储对超出范围的临时对象的引用而搬起石头砸自己的脚。考虑到这是 C++,我发现这很愚蠢。

我不认为你所做的有任何问题。

I don't think it's that a reference to a temporary is undefined, it's just forbidden. Also, I believe this only applies to function arguments. Visual Studio will allow you to pass references to non-const temporaries on the default warning/error level, though I know gcc will not.

As far as I know, doing so is only forbidden so programmers don't shoot themselves in the foot by storing a reference to a temporary that goes out of scope. Considering this is C++, I find that quite stupid.

I don't see any problem with what you're doing.

左岸枫 2024-09-20 18:19:19

你所做的基本上与其中相同

if( istrm >> a >> b ) ...

if( istream.operator>>(a).operator>>(b).operator some_bool_like_type() )

我认为从可用性 POV 来看这很好。 (它当然不存在语法/语义问题。)

但是,与往常一样,隐式转换为 bool 有点令人讨厌,因为它允许编译意外的代码:

if ( CCircleSetter(myCircle).Radius(10) != 10 )

What you're doing is basically the same as in

if( istrm >> a >> b ) ...

which is the same as

if( istream.operator>>(a).operator>>(b).operator some_bool_like_type() )

I think this is fine from a usability POV. (There certainly are no syntactic/semantic problems with it.)

However, as always, implicit conversion to bool is a bit nasty, because it allows unexpected code to compile:

if ( CCircleSetter(myCircle).Radius(10) != 10 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文