2015-04-24 5 views
0

Я не могу понять порядок вызовов конструктора и деструктора? Что будет выполняться первым в этом утверждении A b = f (a)? Может кто-нибудь, пожалуйста, помогите мне?Заказ вызова конструктора и деструктора?

#include<iostream> 
using namespace std; 

class A { 
    int x; 

    public: 
     A(int val = 0) 
     :x(val) { 
      cout << "A " << x << endl << flush; 
     } 
     A(const A& a) { 
      x = a.x; 
      cout << "B " << x << endl << flush; 
     } 
     void SetX(int x) { 
      this->x = x; 
     } 
     ~A() { 
      cout << "D " << x << endl << flush; 
     } 
}; 

A f(A a) { 
    cout << " C " << endl << flush; 
    a.SetX(100); 
    return a; 
} 

int main() 
{ 
    A a(1); 
    A b=f(a); 
    b.SetX(-100); 
    return 0; 
} 

Окно вывода:

A 1 
B 1 
C 
B 100 
D 100 
D -100 
D 1 

Почему печать B 1 в строке 2 окна вывода?

+1

Порядок - это базовые классы в порядке объявленного наследования, члены в порядке деклараций. Другими словами: порядок в списке инициализаторов конструктора не действует (виртуальное наследование является особым). –

+0

Если я правильно понял ваш вопрос, вы получите 'B 1', потому что вы передали объект типа' A' в 'f' по значению (поэтому ему пришлось создать копию и вызвать вызов копии ctor) – Borgleader

+0

@ DieterLücking I ' m не уверен, почему вы говорите о наследовании здесь, есть только один класс ... – Borgleader

ответ

5

«Почему он печатает B 1 в строке 2?»

Поскольку конструктор копирования был вызван из этого заявления

A b=f(a); 

Функция f() требует A передается по значению, при этом копия этого параметра производится на стеке вызовов функций.


Если ваш следующий вопрос должен быть, как вы можете получить за это поведение и избегать вызвать конструктор копирования, вы можете просто передать экземпляр A как ссылка на f():

A& f(A& a) { 
    //^^
     cout << " C " << endl << flush; 
     a.SetX(100); 
     return a; 
    } 

Сторона примечания: endl << flush; избыточно BTW, std::endl включает в себя промывку уже.

Смежные вопросы