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

Wywołanie konstruktora

Ostatnio zmodyfikowano 2016-12-14 21:33
Autor Wiadomość
Lich555
Temat założony przez niniejszego użytkownika
Wywołanie konstruktora
» 2016-12-11 22:46:06
Witam.
Dam przykład:
C/C++
class kolo
{
    float k;
    int a;
    char c;
   
    kolo( float, int, char ) //konstruktor z jakimiś argumentami, nieważne jakimi
};
kolo::kolo( float p, int o, char i )
    : k( p )
     , a( o )
     , c( i )
{ }

int main()
{
    kolo obiekt1( 2.5, 8, 'c' );
    kolo obiekt1 = kolo( 2.5, 8, 'c' ); //tutaj
   
    return 0;
}

Czy pomiędzy tymi dwoma, różnymi z wyglądu, wywołaniami tego samego konstruktora jest jakaś różnica?
P-154803
michal11
» 2016-12-11 23:13:59
Na moje oko teoretycznie, powinien być wywołany konstruktor z parametrem a później kopiujący/przenoszący, ale najpewniej kompilator to odpowiednio zoptymalizuje żeby było tylko jedno wywołanie (co zresztą miało miejsce w moich małych testach).
P-154806
mokrowski
» 2016-12-11 23:28:24
Dla kodu tylko nieznacznie poprawionego...
C/C++
#include <iostream>

class kolo
{
public:
    float k;
    int a;
    char c;
   
    kolo();
    kolo( float, int, char ); //konstruktor z jakimiś argumentami, nieważne jakimi
    kolo( const kolo & src ); // konstruktor kopiujący
    kolo & operator =( const kolo & src ); // operator przypisania
};
kolo::kolo()
{
    std::cout << "konstruktor domyślny" << std::endl;
}
kolo::kolo( float p, int o, char i )
    : k( p )
     , a( o )
     , c( i )
{
    std::cout << "Wołanie konstruktora  argumentami" << std::endl;
}
kolo::kolo( const kolo & src )
    : k( src.k )
     , a( src.a )
     , c( src.c )
{
    std::cout << "Wołanie konstruktora kopiującego" << std::endl;
}
kolo & kolo::operator =( const kolo & src ) {
    std::cout << "Operator przypisania" << std::endl;
    return * this;
}


int main()
{
    kolo obiekt1( 2.5, 8, 'c' );
    kolo obiekt2 = kolo( 2.5, 8, 'c' ); //tutaj
   
    return 0;
}
.. drugie wywołanie (to ze słowem "tutaj") będzie kończyło się optymalizacją http://en.cppreference.com/w/cpp/language/copy_elision
Jeśli dla g++ lub clang++ chcesz wyłączyć optymalizację, dodaj przełącznik:

dla:
clang++ -o kon kon.cpp
wynik:
Wołanie konstruktora  argumentami
Wołanie konstruktora  argumentami

dla:
clang++ -fno-elide-constructors -o kon kon.cpp
wynik:
Wołanie konstruktora  argumentami
Wołanie konstruktora  argumentami
Wołanie konstruktora kopiującego

W C++11 ta optymalizacja była opcjonalna (każdy wytwórca robił jak chciał i np. kompilator VS w trybie debug nie robił optymalizacji) a od C++14 jest ona obowiązkowa.
P-154809
Lich555
Temat założony przez niniejszego użytkownika
» 2016-12-12 09:09:18
Trochę olałem sprawę, ale nie przyłożyłem się do tego kodu, gdyż tak cz. wg mnie była nieistotna. Dla mnie istotne było tylko i wyłącznie różnice w wywołaniu.
1.
C/C++
klasa obiekt( argumenty );
2.
C/C++
klasa obiekt = konstruktor( argumenty );
P-154820
czaffik
» 2016-12-14 21:10:27
1.
C/C++
klasa obiekt( argumenty );
Ten konstruktor po prostu tworzy obiekt i do pól przypisuje podane wartości;
2.
C/C++
klasa obiekt = konstruktor( argumenty );
Ten natomiast tworzy najpierw anonimowy obiekt klasy, przypisuje do pól podane wartości a potem całość kopiuje do obiektu występującego po lewej stronie.

Jeżeli chodzi o efekt końcowy to bez różnicy który zapis zastosujesz, wydaje mi się że drugi sposób będzie nieco wolniejszy aczkolwiek będzie to zapewne tak niewielka różnica że nikt nie zauważy.
No i przede wszystkim w podanym przez ciebie przykładzie wywołanie któregokolwiek konstruktora nie zadziała, bo oba masz private :P
Zapomniałbym, drugiego konstruktora nawet nie napisałeś w swoim kodzie, został utworzony automatycznie przez kompilator, efekt końcowy akurat tutaj będzie ten sam, ale mogą być przypadki kiedy nie będzie ten sam, zwłaszcza gdy będziesz miał wskaźniki.
P-154946
carlosmay
» 2016-12-14 21:33:47
Jeżeli chodzi o efekt końcowy to bez różnicy który zapis zastosujesz, wydaje mi się że drugi sposób będzie nieco wolniejszy aczkolwiek będzie to zapewne tak niewielka różnica że nikt nie zauważy.
Pewnie optymalizacje pominą konstruktor kopiujący lub operator przypisania i w obu przypadkach wywołany zostanie tylko konstruktor z parametrem.
P-154947
« 1 »
  Strona 1 z 1