2009-07-25 2 views
3

Я написал этот небольшой фрагмент кода в C++, вывод также прилагается. Я не понимаю, почему конструктор вызывается только один раз, а я вижу два вызова для деструктора.C++ Constructor call

Из того, что я понимаю, конструктор по умолчанию и перегруженный оператор присваивания должен быть вызван в строке 28.

Может кто-то пожалуйста, пролить некоторый свет на этот счет:

1 #include <iostream> 
    2 using namespace std; 
    3 
    4 class ABC { 
    5 char c; 
    6 public: 
    7  ABC() { 
    8  cout << "default" << endl; 
    9  } 
10  ABC(char c) { 
11  this->c = c; 
12  cout << c << endl; 
13  } 
14  ~ABC() { 
15  cout << hex << this << " destructor " << c << endl; 
16  } 
17  void method() { 
18  cout << "method" << endl; 
19  } 
20  void operator= (const ABC& a) { 
21  cout << "operator" << endl; 
22  } 
23 
24 }; 
25 
26 int main() { 
27 ABC b('b'); 
28 ABC a = b; 
29 } 

Output in g++ version 4.0.1: 
~/src$ g++ test.cpp 
~/src$ ./a.out 
b 
0xbffff0ee destructor b 
0xbffff0ef destructor b 
+0

Что случилось с тегом конструктора? – GManNickG

ответ

11

код вы только вызов конструктора копирования, это определение:

ABC(const ABC& a):c(a.c){ 
    cout << "copying " << hex << &a << endl; 
} 

И вы Шоуда видите такой вывод:

b 
copying 0x7fffebc0e02f 
0x7fffebc0e02e destructor b 
0x7fffebc0e02f destructor b 

Если вы хотите позвонить по умолчанию конструктор, а затем оператор назначения, вы должны использовать два отдельных заявления:

ABC b('b'); 
    ABC a; 
    a = b; 
15
ABC a = b; 

Это acopy constructo r не оператор назначения! Вы можете переопределить это так, что у вас есть компилятор генерируется один:

ABC(const ABC& other) 
{ 
c = other.c; 
cout << c << " copy constructor" << endl; 
} 

Если вы действительно настаиваете на не используя конструктор копирования вы можете добавить оператор converstion как к классу и забыть конструктор копирования!

operator char() 
{ 
    return c; 
} 
+0

Еще лучше, вы можете использовать список инициализации. – 2009-07-25 21:17:34

+0

Да, как и сейчас, конструктор копирования содержит вызов оператора присваивания 'c' в вашем коде –

+0

@litb, который является истинным lol :) – AraK

0

Посмотрите на модифицированный код вашего

#include <iostream> 
using namespace std; 
class ABC { 
    char c; 
public: 

    ABC() { 
     cout << "default" << endl; 
    } 
     ABC(char c) 
     { 
      cout<<"parameterized constructor called\n";/////overloaded constructor called for the first line in main 
      this->c = c; 
      cout << c << endl; 
     } 
     ABC(ABC &c) 
     { 
      cout<<"Copy cons\n";//copy constructor is called for the second line in main 
     } 


     ~ABC() { 
      cout << hex << this << " destructor " << c << endl; 
     } 
     void method() { 
      cout << "method" << endl; 
     } 
     void operator= (const ABC& a) { 

     } 


    }; 


int main() 
{ 
     ABC b('b');//////here parameterized constructor is called i.e <ABC(char c)> 
     ABC a = b;/////////Here the copy constructor is called not the default one.(total 2 object created so the destructor is called twice!) 
} 

Выход программы

parameterized constructor called 
b 
Copy cons 
0x7fff5fbff820 destructor � 
0x7fff5fbff828 destructor b 

Теперь позволяет объяснить, почему конструктор копирования вызывается в 3-х случаях 1.При объект, в инициализированном 2. Когда объект передается как параметр функции 3. Когда объект возвращается из функции.

Если вы не указали свой собственный конструктор копирования, тогда компилятор реализует свой собственный конструктор копирования, который копирует объект по частям. Вы не указали свой собственный конструктор копирования, поэтому вы не можете отслеживать два объекта, созданных из кода. Thanks