Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Vector] push_back wywołuje dwa konstruktory

Ostatnio zmodyfikowano 2017-05-16 10:24
Autor Wiadomość
Paitius
Temat założony przez niniejszego użytkownika
[Vector] push_back wywołuje dwa konstruktory
» 2017-05-15 11:45:45
Podczas tworzenia obiektu po raz pierwszy(kiedy wielkość kontenera jest równa 0) metoda 'push__back' wywołuje konstruktor domyślny, a następnie od razu konstruktor kopiujący. Pytanie jest następujące, dlaczego konstruktor kopiujący jest wywoływany i jak to zniwelować?


klasa.h
C/C++
class klasa
{
public:
    klasa();
    klasa( const klasa & kopia );
};

klasa.cpp
C/C++
klasa::klasa( const klasa & kopia )
{
}

klasa::klasa()
{
}

Projekt1.cpp
C/C++
void nowaklasa( vector < klasa > & spisklas );

int main()
{
    vector < klasa > vectorlist;
   
    nowaklasa( vectorlist );
   
    return 0;
}

void nowaklasa( vector < klasa > & spisklas )
{
    if( spisklas.size() == 0 )
    {
        spisklas.push_back( klasa() );
    }
    else
    {
        spis.push_back( klasa( spisklas.back() ) );
    }
}
P-161139
michal11
» 2017-05-15 11:56:41
Taka charakterystyka vectora, że czasami kopiuje sobie elementy jeżeli musi rozszerzyć swoją wewnętrzną tablicę.

Rozwiązania masz 2, albo w vectorze trzymasz wskaźniki na obiekty i wtedy kopiowane są wskaźniki (najlepiej korzystać wtedy ze smart pointerów), albo możesz użyć listy i wtedy też nie będziesz miał kopiowania obiektów przy modyfikowaniu listy.
P-161141
Monika90
» 2017-05-15 12:22:00
Są więcej niż dwie możliwości, np.
C/C++
spisklas.emplace_back(); //doda obiekt na końcu wektora przy użyciu konstruktora domyślnego

Pokaż co masz w tej klasie, bo być może niepotrzebnie deklarujesz konstruktor kopiujący.
P-161142
Paitius
Temat założony przez niniejszego użytkownika
» 2017-05-15 12:33:29
C/C++
ListaObecnosci::ListaObecnosci()
{
   
    cout << "Pierwsza lista obecnosci, podaj:\n";
    numertygodnia = 1;
   
    cout << "Nazwe placowki: ";
    cin >> placowka;
    cin.clear();
    cin.ignore( 1000, '\n' );
    cout << "\n";
   
    cout << "Imie i nazwisko pierwszego pracownika: ";
    cin >> pracownik1;
    cin.clear();
    cin.ignore( 1000, '\n' );
    cout << "\n";
   
    cout << "Imie i nazwisko drugiego pracownika: ";
    cin >> pracownik2;
    cin.clear();
    cin.ignore( 1000, '\n' );
    cout << "\n";
   
    system( "cls" );
   
    uzupelnienieczasupracy();
    zapisdopliku();
}


C/C++
ListaObecnosci::ListaObecnosci( const ListaObecnosci & kopia )
{
    numertygodnia = kopia.numertygodnia;
    if( kopia.numertygodnia == 52 )
    {
        numertygodnia = 1;
    }
    else numertygodnia++;
   
    placowka = kopia.placowka;
    pracownik1 = kopia.pracownik1;
    pracownik2 = kopia.pracownik2;
   
    uzupelnienieczasupracy();
    zapisdopliku();
   
}

Kiedy kontener jest pusty wywołuje konstruktor domyślny, potem za każdym razem tylko konstruktor kopiujący.

PS: użyłem wskaźników, które faktycznie rozwiązały problem
P-161144
Monika90
» 2017-05-15 12:44:36
Używasz konstruktora kopiującego niezgodnie z przeznaczeniem. Konstruktor kopiujący powinien zainicjalizować kopię obiektu i nic wiecej, kopia ma być równoważna oryginałowi.
P-161145
michal11
» 2017-05-15 12:47:51
Używanie cin i cout w konstruktorze to nie jest zbyt dobra praktyka, klasa powinna być oddzielona od pobierania danych (żeby np. można było zmienić metodę pobierania danych).
P-161146
Paitius
Temat założony przez niniejszego użytkownika
» 2017-05-15 13:03:24
Dziękuję za pomoc i uwagi. Upewnię się, że dobrze zrozumiałem. Konstruktor kopiujący ma wykonywać jedynie kopiowanie, z reszty powinienem zrobić funkcję lub metodę(oczywiście konstruktor kopiujący nie będzie je wywoływał). Nie pobierać danych w metodach, a tworzyć funkcje za to odpowiedzialne.
P-161147
Monika90
» 2017-05-16 10:24:49
Tak byłoby najlepiej.
P-161184
« 1 »
  Strona 1 z 1