当我试图提高我的 c++ 知识时,我从一个旧的编程竞赛中发现了这个问题。今年我会努力参加比赛,所以我要做好准备。
以下程序的输出是什么?
#include <iostream>
using namespace std;
int dat=1;
int counter=0;
class ClassB;
class B {
public:
virtual void f(int d=5)=0;
};
class A {
unsigned i;
public:
int pod;
int index;
A& operator++() { cout<<"A "<<pod--<<dat++<<endl; A* b=new A; return *b; }
A operator++(int) {cout<<"B "<<pod++<<dat--<<endl; A* b=new A; return *b;}
A& operator--() {cout<<"C "<<dat++ <<++pod<<endl; A* b=new A; return *b;}
A operator--(int) {cout<<"D "<<dat--<<--pod<<endl; A* b=new A; return *b;}
void operator+(A& b) {cout<<"Addition Index "<<index<<endl; pod++;}
friend void B::f(int);
A() : i(0), pod(dat) {pod++; index=++counter; cout<<"CA "<<"Index "<<index<<endl; }
~A(){pod++; cout<<"DA Index "<<index<<endl;}
};
const ClassB& returnClassA(const ClassB& p) {return p;}
class ClassB: public A, public B {
public:
void f(int d=2){A c; c++; pod*=d--;}
ClassB(){cout<<"CB Index "<<index<<endl;}
~ClassB(){cout<<"DB Index "<<index<<endl;}
};
ClassB returnClassB(ClassB s) {return s;}
class ClassC : public ClassB {
public:
ClassC(){cout<<"CC Index "<<index<<endl;}
~ClassC(){cout<<"DC Index "<<index<<endl;}
};
ClassB returnClassC(ClassB s){return s;}
int main()
{
ClassC x;
A v,w;
B *c = new ClassB;
--++v--+++w;
returnClassC(returnClassB(returnClassA(x)));
return 0;
}
这应该在纸上解决,但是因为我是初学者,所以我使用了编译器。此外,变量 counter 和 index 是我添加的,因此我可以跟踪正在创建的对象。原来的表达式是--++v--+++w--;但我用 --++v--+++w 改变了它;因为编译器给了我错误。
那个部分:
ClassC x;
A v,w;
B *c = new ClassB;
输出:
- 加州索引 1
- CB指数1
- CC 索引 1
- 加州索引 2
- 加州索引 3
- 加州索引 4
- CB指数4
我明白。
我无法理解下一个表达式 --++v--+++w; 所以一开始我试着理解--++v--++的输出;然后我会添加 +w。
--++v--++的输出;是:
- 11
- 加州索引 5
- 乙 10
- 加州索引 6
- 一个 0 -1
- 加州索引 7
- C 02
- 加州索引 8
- DA 指数 6
- DA 指数 5
这意味着操作的顺序是--(++((v--)++))。为什么会这样?关于首先评估哪些操作是否有一些规则?另外我不明白为什么要调用索引为 6 和 5 的对象的析构函数?
如果我使用原始表达式,--++v--+++w; ,输出为:
- 11
- 加州索引 5
- 乙 10
- 加州索引 6
- 一个 0 -1
- 加州索引 7
- C 02
- 加州索引 8
- 加法索引 8
- DA 指数 6
- DA 指数 5
为什么最后评估 +w 操作?是因为运算符优先级吗?另外,我发现如果我写 cout << v.index 它将返回 2,这意味着 v 仍然是之前创建的原始对象。那么索引为 5-8 的对象去哪里了呢?我怎样才能访问它们?
最后一部分,returnClassC(returnClassB(returnClassA(x))); 输出:
- 数据库索引 1
- DA 指数 1
- 数据库索引 1
- DA 指数 1
- 数据库索引 1
- DA 指数 1
我不明白为什么要调用析构函数?