程序员的政治学
起因是这样的(节选):
标 题: 关于今天C++考试一题的疑问
发信站: 瀚海星云 (2010年01月08日18:35:06 星期五), 站内信件 WWWPOST该题第一问要求补全代码,没问题;第二问要求写运行结果,但我发现这问答案依赖于
编译器。
题目代码有点长,不全贴出来了。main函数:
{
MyComplex a(2,2), b(1,1);
MyComplex c;
c = a + b;
return 0;
}
在MyComplex类中各个构造函数和析构函数均有打印输出。并且重载了operator=和
operator+:
const MyComplex& operator=(const MyComplex& other){
rpart = other.rpart;
ipart = other.ipart;
cout << "Overriding operator=: " << endl;
return *this;
}
MyComplex operator+(const MyComplex& com){
cout << "Overriding operator+ : " << endl;
//return MyComplex(rpart + com.rpart, ipart + com.ipart);
MyComplex temp;
temp.rpart = rpart + com.rpart;
temp.ipart = ipart + com.ipart;
return temp;
}
我也参加了这场考试,并且凑巧的是前一天用g++测试过类似的代码,得到的结果是c = a + b中不会调用MyComplex类的拷贝构造函数(MyComplex类有拷贝构造函数),于是不假思索就写上去了。但随后就发现确实有问题。
问题主要集中在临时变量temp的析构时间。按照书上的理论,temp在operator+运行完以
后应该立即析构,并且由于返回值是类实例,因此编译器会隐式的构造一个新的类实例
,用拷贝构造函数构造,并且将这个不可见的实例的const引用作为operator=的参数传
递进去,在operator=执行完毕后析构。
C++中的确有变量离开作用域就应当被销毁的原则,按照这样的原则,应当得到如下结果:
ConstructorB : 1
ConstructorB : 2
Constructor : 3
Overriding operator+ :
Constructor : 4
Copy constructor : 5
Destructor : 4
Overriding operator=:
Destructor : 3
Destructor : 2
Destructor : 1
Destructor : 0
但g++给出的结果的确是:
ConstructorB : 1
ConstructorB : 2
Constructor : 3
Overriding operator+ :
Constructor : 4
Overriding operator=:
Destructor : 3
Destructor : 2
Destructor : 1
Destructor : 0
我不相信g++有错,于是去翻查了《ISO C++ Standard (ISO14882) 2003》,发现这里的确留了个口子,而且限定严格,适用范围极小,几乎就是专门为这个题目打造的——3.7.2.3节中规定,12.8中有各种特殊情况,除此以外按6.7节处理,而12.8.15节完全就是这个题目。看来,我们又遇到了一位没有耐心的把757页的C++标准看完的出题人。不过这也怪不得他,标准委员会的思维跳跃幅度,岂是我辈可比?如此冗长的标准,手段已经堪比律师和国会议员了。
试卷上还有一题是问“位拷贝”的。不知道是谁发明了“位拷贝”这个概念,它是绝对错误的,C++标准中从来没有这样混乱的概念。标准中对编译器合成的拷贝构造函数的描述在12.8.8节,大致做的是按默认构造函数中基类和成员的初始化的顺序,依次调用其拷贝构造函数(数组类型和内置类型按值拷贝)。
Operation Aurora终于让长久以来不满于李开复的妥协政策的Sergey Brin找到了爆发点。我们见惯了不为五斗米折腰的人,今天,终于见到了宁可不赚钱,也要坚持自己的价值观的企业。(那些认定Google此举所谋者大的循环论证,请不要来打扰评论区了。)

2 Responses
orz 膜拜标准帝!
Reply
orz你一直在研究这神奇的东西么....c++标准太恶心了...
Reply