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

Inicjalizacja tablic obiektow

Ostatnio zmodyfikowano 2017-06-26 20:24
Autor Wiadomość
pimpek
Temat założony przez niniejszego użytkownika
Inicjalizacja tablic obiektow
» 2017-06-26 16:36:34
Cześć.
Zastanawiam sie nad takim przykladem:
C/C++
#include <iostream>
#include <string>
using namespace std;

class Zwierze
{ string imie;
    int wiek;
public:
    Zwierze( void )
        : imie( "BRAK" )
         , wiek( 0 )
    { } // KONSTRUKTOR
    Zwierze( const string im, int lata )
        : imie( im )
         , wiek( lata )
    { } //KONSTRUKTOR 2
   
    Zwierze( Zwierze & obiekt )
        : imie( obiekt.imie )
         , wiek( obiekt.wiek )
    {
        cout << "Jestem tylko kopia";
    } // KONSTRUKTOR KOPIUJACY
   
    void pokaz()
    { cout << "Mam na imie:" << imie << " i mam lat:" << wiek << endl;
    }
};


int main()
{ Zwierze kotek;
    Zwierze kot[ 10 ]
    = { kotek, // chce zeby byl kopia czyli kot[0]==kotek.
        Zwierze(), // chce zeby kot[1] == imie"BRAK", wiek(0) = czyli konstruktor domyslny
        Zwierze( "Burek", 3 ) // chce zebykot[2] == imie"burek",wiek(3) == czyli konstruktor z argumentami string i int
    }
Wyskakuja mi bledy ze jest zbyt wiele kandydatow na przeladowanei operatora. Nie rozumiem dlaczego, gdyby ktos byl laskaw mi to wyjasnic.
i pokazac jak powinno wygladac poprawne wywolanie tego.
Dzieki
P-162844
mokrowski
» 2017-06-26 17:14:40
C/C++
#include <iostream>
#include <string>

class Zwierze {
    std::string imie;
    int wiek;
public:
    Zwierze()
        : imie( "BRAK" )
         , wiek( 0 )
    { } // KONSTRUKTOR
    Zwierze( const std::string & im, int lata )
        : imie( im )
         , wiek( lata )
    { } //KONSTRUKTOR 2
   
    Zwierze( const Zwierze & obiekt )
        : imie( obiekt.imie )
         , wiek( obiekt.wiek )
    {
        std::cout << "Jestem tylko kopia";
    } // KONSTRUKTOR KOPIUJACY
   
    void pokaz() const {
        std::cout << "Mam na imie:" << imie << " i mam lat:" << wiek << std::endl;
    }
};


int main() {
    Zwierze kotek;
    Zwierze kot[ 10 ]
    = { kotek, // chce zeby byl kopia czyli kot[0]==kotek.
        Zwierze(), // chce zeby kot[1] == imie"BRAK", wiek(0) = czyli konstruktor domyslny
        Zwierze( "Burek", 3 ) // chce zebykot[2] == imie"burek",wiek(3) == czyli konstruktor z argumentami string i int
    };
}
A jak znajdziesz różnicę której nie potrafisz wyjaśnić, pytaj.
P-162845
pimpek
Temat założony przez niniejszego użytkownika
Roznica
» 2017-06-26 17:39:57
i tylko, ten modyfikator const tyle zmienia?
dlaczego?
P-162847
Monika90
» 2017-06-26 18:18:14
Argumentem funkcji której parametr jest typu T& nie może być obiekt tymczasowy, a w przypadku const T& może być.

W starym C++, takie coś
C/C++
Zwierze kot[ 1 ] = { Zwierze() };
oznaczało utworzenie obiektu tymczasowego Zwierze(), a następnie utworzenie obiektu kot[0] za pomocą konstruktora kopiującego. Twój konstruktor kopiujący nie nadawał się do zrobienia kopii obiektu tymczasowego, bo brakowało const w parametrze. W praktyce konstruktor kopiujący mógł nie być wywołany w takiej sytuacji (tzw. copy elision), ale i tak musiał istnieć nadający się do użycia konstruktor kopiujący.

W C++17 Twój kod da się skompilować bez zmian, ale i tak parametr konstruktora kopiującego powinien mieć const, bo są inne istotne powody ku temu.
P-162849
pimpek
Temat założony przez niniejszego użytkownika
..
» 2017-06-26 18:32:20
Aha, rozumiem.
a co w przypadku tych pozostalych, obiektow ktorych jawnie nie zainicjowalem?
 np.
kotek[8]?   rozumiem ze w przypadku jawnym zainicjowania tego obiektu czyli:
 kotek[8]={Zwierze()} - jest uruchamiany konstruktor(bezargumentow)dla Zwierze(obiekt tymczasowy), a pozniej
odpala sie konstruktor kopiujacy do utworzonego przed chwila obiektu kotek[8]? ( i w tym wypadku konstruktor kopiujacy musi byc const).  a jak jawnie nie wywolam inicjalizacji kotke[8] ( czyli wgl go nie napisze miedzy klamrami?) czy wtedy nie jest identyczny tok postepowania kompilatora?
P-162850
Monika90
» 2017-06-26 18:39:58
Dla tych elementów tablicy, których nie zaincjalizowałeś jawnie, wywołany będzie konstruktor domyślny, konstruktor kopiujący nie będzie brał w tym udziału.
P-162851
mokrowski
» 2017-06-26 20:24:27
Dodać jeszcze trzeba że warto dbać o opatrzenie metod które nie modyfikują atrybutów klas słowem kluczowym const. To zapewnia dodatkową kontrolę a słowo kluczowe const na liście przekazywanych parametrów (wskaźnik lub referencja), pozwala uniknąć zbędnego kopiowania.
P-162852
« 1 »
  Strona 1 z 1