Пока я пытался улучшить свои знания 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;
выходы:
Что я понимаю.
У меня проблемы с пониманием следующего выражения, — ++ v — +++ w; поэтому сначала я попытался понять вывод — ++ v — ++; и тогда я бы добавил + ш.
Вывод — ++ v — ++; является:
Это означает, что порядок операций — (++ ((v -) ++)).
Почему это так? Есть ли какое-то правило относительно того, какие операции оцениваются первыми?
Также я не понимаю, почему называются деструкторы объектов с индексами 6 и 5?
Если я использую оригинальное выражение, — ++ v — +++ w; ,
выход:
Почему операция + w оценивается последней? Это из-за приоритета оператора?
Кроме того, я узнал, что если я напишу cout << v.index возвращает 2, что означает, что v все еще является исходным объектом, созданным ранее. Так куда же деваются объекты с индексами 5-8? Как я могу получить к ним доступ?
Последняя часть, returnClassC (returnClassB (returnClassA (x)));
выходы:
Я не понимаю, почему называются деструкторы?
Несколько вещей, на которые стоит обратить внимание
Когда вы перегружаете операторы в C ++, есть кое-что, что нужно знать, например, ++, вы можете сделать предварительный код
++i
или пост увеличение
i++
чтобы сообщить компилятору о том, что вы перегружаете, у вас не должно быть параметров или целого числа в сигнатуре
A operator++(int)
перегружает пост инкремент,
A& operator++()
перегрузки пред приращением
В C ++ дескриптор объекта вызывается в двух случаях
Вы вызываете delete для указателя на объект, выделенный с помощью new
A* = new A(); //constructor is called
delete(A);//destructor is called
Вы оставляете контекст для объекта, созданного в стеке
if(something) {
A a();
...
} //here a's destructor is called because a no longer exists
Заметьте в своем коде, как некоторые операторы возвращают копию, другие возвращают ссылку.
A operator++(int)
эта функция возвращает копию. Это означает, что когда вы вызываете эту конкретную функцию, конструктор вызывается один раз внутри функции для нового вызываемого A, а затем снова, когда вы возвращаетесь из функции, поскольку копируется объект, на который указывает b.
Вы можете найти некоторую информацию о приоритете операторов [здесь] (http://en.cppreference.com/w/cpp/language/operator_precedence)
Я заметил, что некоторые люди говорят вам, что изучать такой код бесполезно. Я согласен, что кодирование таким способом довольно плохо, но оно может многому научить вас, как работают конструкторы / деструкторы, куча / стек и операторы в C ++. Вероятно, есть лучшие способы обучения, мне кажется, это «промежуточный экзамен».
Других решений пока нет …