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

Konstruktor kopiujący i konwertujący - "kłótnia"

Ostatnio zmodyfikowano 2016-12-26 15:54
Autor Wiadomość
latajacaryba
Temat założony przez niniejszego użytkownika
Konstruktor kopiujący i konwertujący - "kłótnia"
» 2016-12-25 22:20:39
Witam. Mam kod
C/C++
class T
{ public:
    double a;
    double b;
    T( double aa )
    {
        a = aa;
        b = 0;
    }
};


class K
{
    double a;
    double b;
public:
    K( T obiekt )
    {
        a = obiekt.a;
        b = obiekt.b;
    }
    K( double aa, double bb = 0 )
    {
        a = aa;
        b = bb;
    }
    K( K & obiekt )
    {
        a = obiekt.a;
        b = obiekt.b;
        cout << "kopiujacy!" << endl;
    }
    friend K dodaj( K obiekt, K obiekt2 );
};
K dodaj( K obiekt, K obiekt2 )
{
    K wynik( 0, 0 );
    wynik.a = obiekt.a + obiekt2.a;
    wynik.b = obiekt.b + obiekt2.b;
    return wynik;
}
int main()
{
    K obiekt( 2.5, 3.0 );
    K suma( 0, 0 );
    suma = dodaj( obiekt, 3.4 );
}
I jest błąd związany z funkcją:

||=== Build: Debug in Laptop1 (compiler: GNU GCC Compiler) ===|
C:\C++\Laptop1\main.cpp||In function 'int main()':|
C:\C++\Laptop1\main.cpp|49|error: no matching function for call to 'K::K(K)'|
C:\C++\Laptop1\main.cpp|49|note: candidates are:|
C:\C++\Laptop1\main.cpp|30|note: K::K(K&)|
C:\C++\Laptop1\main.cpp|30|note:   no known conversion for argument 1 from 'K' to 'K&'|
C:\C++\Laptop1\main.cpp|25|note: K::K(T)|
C:\C++\Laptop1\main.cpp|25|note:   no known conversion for argument 1 from 'K' to 'T'|
C:\C++\Laptop1\main.cpp|20|note: K::K(double, double)|
C:\C++\Laptop1\main.cpp|20|note:   no known conversion for argument 1 from 'K' to 'double'|
C:\C++\Laptop1\main.cpp|38|error:   initializing argument 2 of 'K dodaj(K, K)'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Kiedy usunę z kodu konstruktor kopiujący i konstruktor K(T obiekt) to działa. Dlaczego? Domyślam się, że kompilator nie wie, czy w funkcji chcemy skonstruować obiekt za pomocą K(T) (a w konstruktorze klasy T podajemy jeden argument typu double) w ten sposób:
K(T(3.4) ); - i tak "wygenerowany" obiekt klasy K przesłać do funkcji,
Lub, czy chcemy wykorzystać konstruktor kopiujący K(K & obiekt) w ten sposób:
K(K(3.4) );
Czy moje rozumowanie jest poprawne?

I jeszcze jedno:
Po co używać tego konstruktora konwertującego, skoro zamiast pisac tak:
suma = dodaj( obiekt, 3.4 )
możemy równie łatwo napisać:
suma = dodaj( obiekt, K( 3.4 ) )
 przy czym tu, nie musimy ograniczać się do podawania jeden zmiennej, np
suma = wynik( obiekt, K( 3.4, 2.8 ) )
Z góry dzięki
P-155422
michal11
» 2016-12-25 22:59:38
Konstruktor kopiujący powinien przyjmować stałą referencję.

W twoim main nigdzie nie jest wykorzystywany konstruktor K(T) przecież.
P-155425
1aam2am1
» 2016-12-25 23:12:26
K(const K & obiekt )
P-155426
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-12-26 00:13:35
Źle wytłumaczyłem swoje domysły
Chodziło mi o to:
Kiedy usunę z kodu konstruktor kopiujący i konstruktor K(T obiekt) to działa. Dlaczego?
To pytanie było odnośnie tego fragmentu kodu:
suma = dodaj( obiekt, 3.4 );
Powinna wystąpić tu konwersja, a jest w/w w logu błąd
P-155431
carlosmay
» 2016-12-26 00:26:32
@1aam2am1 dał ci już wskazówkę. Wystarczy dodać do konstruktora kopiującego
const
,
bo kompilator nie wie jak skonwertować wartość stałą do referencji.
Pozostałe błędy wynikają z tego jednego.

Kiedy usunę z kodu konstruktor kopiujący i konstruktor K(T obiekt) to działa. Dlaczego?
Widocznie kompilator umie lepiej dopisać sobie konstruktor kopiujący.
P-155433
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-12-26 01:36:21
bo kompilator nie wie jak skonwertować wartość stałą do referencji.
Co to jest konwertowanie wartości stałej do referencji? Gdzie taka konwersja wg Ciebie następuje? Jest tylko
suma = dodaj( obiekt, 3.4 );
 ale tu jest konwersja double->Klasa K
P-155441
1aam2am1
» 2016-12-26 03:01:13
Funkcja dodaj przyjmuje obiekt jako kopie czyli z domysłu nie powinna go zmienić. Lecz twój konstruktor kopjujacy przyjmuje referencje czyli może zmienić właściwości obiektu. Kompilator nie może dopuścić do czegoś takiego. Więc zwykle zapewnienie kompilatora że konstruktor kopjujacy nie zmieni obiektu który przekazujemy przez kopie, jest wystarczający.

PS. Kompilator potrafi sam sobie wygenerować konstruktor kopjujacy gdy taki nie jest opisany. (I przyjmuje on const referencje to object)

PS2. obiekt->konstruktor kopjujacy->obiekt w funkcji
Obiekt w funkcji nie może zmienić obiektu po za nią gdyż niema tam referencji. Więc konstruktor kopjujacy też nie powinien dlatego wystarczy dać const
P-155442
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-12-26 15:54:19
Już rozumiem, dzięki :)
P-155452
« 1 »
  Strona 1 z 1