2010-08-09 30 views
1

问候,大家!链接方法和临时变量,请澄清

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

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)) 
{ ... } 

,一方面,我认为临时对象,内部创建的“如果”的表情,会活到这个表达式的结尾。所以,对“Radius”和“Center”的呼叫是合法的。但另一方面,使用对临时变量的引用是一个未定义的行为,在我看来,我正在做这种事情 - 使用(* this),其中“this”是一个临时变量。它给了我一些疑问,请澄清。谢谢!

+0

“的链接方法”:这似乎是尝试[流畅的界面](http://en.wikipedia.org/wiki/Fluent_interface)或许? – 2010-08-10 07:58:44

+0

感谢您的链接。从维基百科:“一个流畅的界面不仅仅需要方法链接”=) – SadSido 2010-08-10 09:10:57

回答

2

不,在这个非常特殊的情况下,这很好,因为临时会在整行完成后被销毁,但通常非常难以持有临时参考。

+0

“临时将在整行完成后被破坏” - 这正是我想听到的。任何对标准的引用? – SadSido 2010-08-10 15:10:32

+0

C++ 11的参考文献在第12.2章*第3段中: 临时对象作为评估完整表达式的最后一步被销毁。9)(词汇上)包含它们被创建的点。' – Pixelchemist 2014-02-04 14:47:44

0

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

据我所知,这样做只是被禁止的,所以程序员不要通过存储对超出范围的临时引用来引起自己的注意。考虑到这是C++,我觉得很愚蠢。

我没有看到你在做什么的问题。

1

即使它是一个临时变量,这并不意味着它的所有成员都是临时变量。在临时对象的范围内,this指针和其他成员不是临时的。你的代码完全没问题。现在,如果你做了这样的事情:

SomeFunc(&CCircleSetter(myCircle)) 

这将是一个临时变量的引用。

0

你正在做什么是基本相同

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

这是一样的

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

我觉得这是从可用性的POV罚款。 (当然有没有与它的句法/语义问题。)

然而,一如既往,隐式转换为BOOL是有点讨厌,因为它允许意外的代码进行编译:

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

是的,同样的事情。但在这个例子中,istream不是一个变量,在“if”表达式中创建 - 没有调用istream的构造函数/析构函数。这是我的问题的重点。 至于意外的代码:是(true!= 10)一个合法的表达式? – SadSido 2010-08-10 06:58:31

+0

@SadSido:'bool'隐式转换为'int',所以我认为这应该编译。但即使不行,“操作员布尔”也是一种卑鄙的野兽。我曾经遇到过一个智能指针实现,其中创建者忘记重载'<'。当你把它们塞进一个'std :: map'中时,它的'operator bool'来到“rescue”,并且地图比较了这个结果。一个空指针比非空指针小,而所有的空指针都是相同的。所以你最终在地图上最多有2个项目。这花了一段时间来调试,直到我找到缺少的比较运算符... – sbi 2010-08-10 07:38:09