1

在如下所示的表达式中,我不清楚临时假设是否为 const 类型。

#include <iostream>

class X {
public:
X(int a) { i = a; cout << "X(int) [" << (int)this << "]" << endl; }

X& operator+(const X& x) 
{ 
i += x.i; 
cout << "X operator+(const X&) [" << (int)this << "]" << endl; 
return *this; 
}

~X() { cout << "~X [" << (int)this << "]" << endl; }

private:
int i;
};


int main() 
{
X x = X(3) + X(4);
cout << "done" << endl;

return 0;
}

X(3)表现得像非常量(因为我可以调用operator+,而X(4)表现得像 const(因为它需要 const 参数operator+)。

有人可以澄清一下,正确的理解是什么?

4

4 回答 4

2

您可以呼叫非const临时成员。但是您不能将非const引用绑定到临时对象。

于 2011-11-16T09:11:17.607 回答
2

对于类类型,当您创建一个 const 类型的临时对象时,该临时对象将是 const。当您创建一个非常量类型的临时对象时,该临时对象将是非常量的。就是这样。即,就确切的类型而言,const 和临时变量之间根本没有任何联系。临时类类型永远不会自己假设 const 。是你可以明确地将 const 强加于它。

在您的示例中,constX(3)也不是。X(4)由于X(3)不是 const,因此您可以在其上调用非常量方法。

说你的X(4)“表现得像 const”是不正确的。在您的示例中,没有任何迹象表明它“表现得像 const”。仅仅因为您能够用某物初始化 const 引用并不意味着某物是 const。

在您的问题中,您声明您“需要 const 参数operator+”。这是不正确的。您不需要 const参数operator+。您的参数 x被声明为 const 引用。一个 const 引用可以很容易地绑定到 const 参数以及非 const 参数。在您的情况下, const 引用参数x绑定到非 const 临时参数X(4)

于 2011-11-16T09:11:26.450 回答
2

从历史上看,临时变量是右值,而右值不是(也不能是)cv 限定的。该规则适用于非类类型,或没有成员函数的类类型;由于 const-ness 干预函数重载解析,因此必须保持临时的 cv 限定。如果一个函数简单地返回X,那么临时 不是const,你可以在它上面调用非 const 函数;如果函数返回X const,则临时为 const,您不能在其上调用非 const 函数。作为一般规则,最好将类类型返回为const; 即X const f(),而不是X f(). 但肯定有例外,没有机构这样做,即使在更合适的情况下也是如此。最后,在某些情况下,您无法指定 const-ness(例如函数样式类型转换),其中语法不提供指定 cv 限定符的方法(使用 typedef 除外)。

您可能希望查看以下代码的输出:

class C
{
    std::string myComment;
public:
    C( std::string const& comment ) : myComment( comment ) {}

    void f()
    {
        std::cout << "Non const " << myComment << std::endl;
    }

    void f() const
    {
        std::cout << "Const " << myComment << std::endl;
    }
};

typedef C const CC;

C
c()
{
    return C("function return value");
}

C const
cc()
{
    return C("function return value");
}

int
main()
{
    C("function style conversion").f();
    CC("function style conversion").f();
    c().f();
    cc().f();
}
于 2011-11-16T10:02:55.057 回答
1

在以下代码中:

X x = X(3) + X(4);

X(3)创建一个调用 的临时非常量对象operator+,将X(4)另一个临时非常量对象作为常量引用参数传递给函数。

非 const 对象可以作为 const 对象(通过引用传递)传递给函数,但 const 对象不能通过非 const 引用传递给函数。这就是区别。

于 2011-11-16T09:12:26.653 回答