在 C 编程语言中,右值(右手值)通常不能用作左值(左侧值)。但是,此规则也有例外,如以下代码所示:
<code class="cpp">class Y { public: explicit Y(size_t num = 0) {} }; int main() { Y(1) = Y(0); // WHAT?!? return 0; }</code>
令人惊讶的是,即使构造函数 Y(1) 返回的对象是右值,此代码也能成功编译。本文探讨了这种意外行为背后的原因。
理解此代码为何有效的关键在于合成成员函数的概念。对于没有显式定义赋值运算符的类,编译器会生成默认赋值运算符。这个默认运算符是一个成员函数,它将对同一类的对象的引用作为其参数。
在上面的示例中,类 Y 的赋值运算符合成如下:
<code class="cpp">Y& Y::operator=(const Y& other);</code>
值得注意的是,这个合成赋值运算符是一个非常量成员函数。这意味着它可以应用于左值(引用的对象)和右值(未引用的对象)。
当使用返回右值的构造函数创建对象时,编译器在内存中生成一个临时对象。该临时对象将在创建它的语句结束时自动销毁。但是,在构造函数返回类类型的右值的情况下,合成赋值运算符可以延长临时对象的生命周期。
赋值语句 Y(1) = Y(0);是以下代码的语法糖:
<code class="cpp">Y(1).operator=(Y(0));</code>
正如我们所确定的,类 Y 的合成赋值运算符 operator= 是一个非常量成员函数,这意味着它可以应用于右值。因此,编译器可以将赋值语句解释为对构造函数 Y(1) 创建的临时对象的赋值。
与通常预期的相反,可以赋值为 C 中类类型的右值,因为编译器会为没有显式定义的赋值运算符的类合成非常量赋值运算符。这些合成的赋值运算符延长了构造函数创建的临时对象的生命周期,允许对右值进行赋值。
以上是您可以在 C 中分配给类类型的右值吗?的详细内容。更多信息请关注PHP中文网其他相关文章!