push_back wywołuje destruktor - dlaczego?

1

Poniżej przykład:

//---------------------------------------------------------------------------

#include <vcl.h>
#include "test.h"
#include <iostream>
#include <vector.h>
#pragma hdrstop
//---------------------------------------------------------------------------

#pragma argsused
using namespace std;
int main(int argc, char* argv[])
{
 vector<test> g;
// test t1, t2;

// g.push_back(test(3));
 g.reserve(10);
 g.push_back(test(4));
 g.push_back(test());

 cout<<"liczba ob: "<<g.size()<<endl;
 g.pop_back();

        getchar();
        return 0;
}
//---------------------------------------------------------------------------

i plik test.h:

#include <iostream>
using namespace std;
class test
{
 private:
 int x;

 public:
 test()
 {
  x=5;
    cout<<"const"<<endl;
 }

 test(int i)
 {
  x=i;
    cout<<"const i"<<endl;
 }

 ~test()
 {
  cout<<"dest"<<endl;
 }
};

a oto rezultat:
const i
dest
const
dest
liczba ob: 2
dest

Dlaczego tak się dzieje?

0

Wektor trzyma kopii.
przykazałeś do push_back wartość test(4)
po zakończeniu przekazywania tej wartości trzeba ten obiekt usunąć, odbywa się to automatycznie.

0

OK rozumiem, ale jak w tym wypadku mogę zapobiec takiej sytuacji:

#include "test.h"
#include <iostream>
#include <vector.h>
#pragma hdrstop
//---------------------------------------------------------------------------

#pragma argsused
using namespace std;
int main(int argc, char* argv[])
{
 vector<test> g;

 for(int i=0; i<2; i++)g.push_back(test());
 for(int i=0; i<2; i++)for(int j=0; j<5; j++)cout<<i<<" "<<g[i].x[j]<<endl;
 cout<<"liczba ob: "<<g.size()<<endl;

        getchar();
        return 0;
}

plik test.h:

#include <iostream>
using namespace std;
class test
{
  public:
 int *x;

 test()
 {
  x = new int[5];
  for(int i=0; i<5; i++)x[i]=5;
 }

 ~test()
 {
  delete [] x;
 }
};

Wynik jaki otrzymuje to:
0 "śmieci"
0 "śmieci"
0 0
0 0
0 0
1 0
1 "śmieci"
1 0
1 0
1 0
liczba ob: 2

Oczywiście jeśli w destruktorze nie zwalniam pamięci to wszystko jest ok. Co z tym zrobić?

1

Przydałby się konstruktor przesuwający, ale nie napisałeś jaki masz kompilator, więc nie wiemy czy to obsłuży. Zdefiniuj w klasie konstruktor kopiujący:

test(const test &b)
{
  x = new int[5];
  for (int i=0; i<5; i++) x[i] = b.x[i];
}
0

Dzięki wielkie, rzeczywiście konstruktor kopiujący rozwiązuje problem.
Korzystam z Borland C++ Builder 6

1

Sam konstruktor kopiujący to może okazać się za mało, trzeba jeszcze przeciążyć operator=.

1 użytkowników online, w tym zalogowanych: 0, gości: 1