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 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 |
|
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ż. |
|
1aam2am1 |
» 2016-12-25 23:12:26 K(const K & obiekt ) |
|
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 |
|
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. |
|
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 |
|
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 |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2016-12-26 15:54:19 Już rozumiem, dzięki :) |
|
« 1 » |