执行期语义学——导读

问题实例

 
当前我们有一个简单的表达式:

1
if(yy==xx.getValue()) ...

其中xx与yy分别有定义为:
1
2
X xx;
Y yy;

而X与Y有定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class X{
public:
X();
~X();
operator Y() const;
X getValue();
...
}
class Y{
public:
Y();
~Y();
bool operator==(const Y&) const;
...
}


问题剖析

 
在得到了上述定义之后,我们对之前那个简单的表达式进行剖析。
首先,我们决定equality运算符所参考到的真正实体。在本次实例中,它被resloved为“被overloaded的Y成员实体”。下面是该表达式的第一次转换:

1
if(yy.operator==(xx.getValue()))

Y的equality运算符需要一个类型为Y的参数,然而getValue()传回的却是一个类型为X的object,因此,在实际执行时,上述表达式发生了隐式转换:
1
if(yy.operator==(xx.getValue().operator Y()))

上述扩张是编译器根据class的语意自动补全的操作,你可以明确地写出它们,这样编译速度可能会快上一丢丢。

实际上这并非上述表达式的完全形态,在实际使用中我们生成了相对应的临时对象,用来放置函数调用所传回的值,最终,实际表达式被扩张成为:

1
2
3
4
5
6
7
8
{
X temp1 = xx.getValue();
Y temp2 = temp1.operator Y();
int temp3 = yy.operator==(temp2);
if(temp3) ....
temp2.Y::~Y();
temp1.X::~X();
}

如此看来,这个表达式似乎并不简单。这也是C++的一大困难之处:无法从程序代码看出表达式的复杂程度。在本章,我们将升入探究执行期所发生的一些转换。