输出c ++程序

时间:2013-04-18 17:55:37

标签: c++ prefix operator-precedence postfix-notation

在我努力提高我的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;

}   

这应该在纸上解决,但因为我是初学者,所以我使用了编译器。 此外,我添加了变量计数器和索引,因此我可以跟踪正在创建的对象。最初的表达是 - ++ v - +++ w--;但是我改为 - ++ v - +++ w;因为编译器给了我错误。

部分:

ClassC x;      
A v,w;               
B *c = new ClassB;

输出:

  1. CA Index 1
  2. CB Index 1
  3. CC Index 1
  4. CA Index 2
  5. CA Index 3
  6. CA Index 4
  7. CB Index 4
  8. 我理解。

    我有理解下一个表达式的问题, - ++ v - +++ w;所以一开始我试着理解 - ++ v - ++的输出;然后我会添加+ w。

    - ++ v - ++的输出;是:

    1. D 11
    2. CA Index 5
    3. B 10
    4. CA Index 6
    5. A 0 -1
    6. CA Index 7
    7. C 02
    8. CA Index 8
    9. DA Index 6
    10. DA Index 5
    11. 这意味着操作的顺序是 - (++((v - )++))。 为什么会这样?是否有一些关于首先评估哪些操作的规则? 另外我不明白为什么调用索引6和5的对象的析构函数?

      如果我使用原始表达式, - ++ v - +++ w; , 输出是:

      1. D 11
      2. CA Index 5
      3. B 10
      4. CA Index 6
      5. A 0 -1
      6. CA Index 7
      7. C 02
      8. CA Index 8
      9. 加法指数8
      10. DA Index 6
      11. DA Index 5
      12. 为什么最后评估+ w操作?是因为运营商优先吗? 另外,我发现如果我写cout&lt;&lt; v.index它将返回2,这意味着v仍然是之前创建的原始对象。那么索引5-8的对象去哪里了?我该如何访问它们?

        最后一部分,returnClassC(returnClassB(returnClassA(x))); 输出:

        1. DB Index 1
        2. DA Index 1
        3. DB Index 1
        4. DA Index 1
        5. DB Index 1
        6. DA Index 1
        7. 我不明白为什么要调用析构函数?

1 个答案:

答案 0 :(得分:0)

有几点需要注意 当你在C ++中重载运算符时,有一些事情需要知道,例如++你可以做一个preincrement

++i

或后增量

i++

为了告诉编译器你正在重载,你需要在签名中没有参数或int

A operator++(int) 

正在重载帖子增量,

A& operator++() 

重载预增量

在C ++中,在两种情况下调用对象的析构函数

  1. 在指向使用新

    分配的对象的指针上调用delete
    A* = new A(); //constructor is called
    delete(A);//destructor is called
    
  2. 您为堆栈上创建的对象保留上下文

    if(something) {
        A a();
        ...
    } //here a's destructor is called because a no longer exists
    
  3. 请注意,在您的代码中,某些运算符如何返回副本,其他运算符则返回引用。

    A operator++(int) 
    

    此函数返回一份副本。这意味着当您调用此特定函数时,构造函数将在函数内部被调用一次,该函数将被调用,然后再次从函数返回时,正在复制b指向的对象的副本。 / p>

    您可以在运算符优先级[here](http://en.cppreference.com/w/cpp/language/operator_precedence

    中找到一些信息

    我注意到有些人告诉你,从这样的代码中学习是没用的。我同意以这种方式编码非常糟糕,但它可以教你很多关于构造函数/析构函数,堆/堆栈和运算符如何在C ++中工作。可能有更好的学习方式,这对我来说似乎是“中期考试”。