Czy możesz przypisać jedną instancję struktury do innej, na przykład:
struct Test t1;
struct Test t2;
t2 = t1;
Widziałem, jak działa w przypadku prostych struktur, ale czy działa w przypadku złożonych struktur?
Skąd kompilator wie, jak kopiować elementy danych w zależności od ich typu, tj. Rozróżniając int
ciąg i łańcuch?
Tak, przypisanie jest obsługiwane w przypadku struktur. Istnieją jednak problemy:
Teraz wskaźniki obu struktur wskazują na ten sam blok pamięci - kompilator nie kopiuje wskazanych danych. Obecnie trudno jest stwierdzić, która instancja struktury jest właścicielem danych. Właśnie dlatego C ++ wymyślił koncepcję definiowanych przez użytkownika operatorów przypisania - możesz napisać określony kod, aby obsłużyć ten przypadek.
źródło
struct
same w sobie są wyraźnie skopiowane.Najpierw spójrz na ten przykład:
Kod w C dla prostego programu w C jest podany poniżej
Równoważny kod ASM dla foo_ assign () to
Jak widać, przypisanie jest po prostu zastępowane przez instrukcję „mov” w asemblerze, operator przypisania oznacza po prostu przenoszenie danych z jednej lokalizacji pamięci do innej. Przypisanie zrobi to tylko dla bezpośrednich członków struktur i nie powiedzie się, jeśli masz w strukturze złożone typy danych. Tutaj LICZBA.ZESP oznacza, że nie możesz mieć tablicy wskaźników wskazujących na listy.
Tablica znaków w strukturze sama nie będzie działać na większości kompilatorów, ponieważ przypisanie będzie po prostu próbowało skopiować, nawet nie patrząc, czy typ danych jest złożony.
źródło
To jest prosta kopia, tak jak byś to zrobił
memcpy()
(w rzeczywistości niektóre kompilatory faktycznie tworzą wywołaniememcpy()
dla tego kodu). W C nie ma „łańcucha”, tylko wskazuje na kilka znaków. Jeśli twoja struktura źródłowa zawiera taki wskaźnik, to wskaźnik zostanie skopiowany, a nie same znaki.źródło
memcpy
, zobacz tutaj: godbolt.org/z/nPxqWc - Ale teraz, jeśli przekażę identyczne wskaźnikia
ib
, i*a = *b
zostanie przetłumaczone namemcpy
niezdefiniowane zachowanie, ponieważ dlamemcpy
„Obszary pamięci nie mogą się pokrywać”. (cytat ze strony podręcznika). Czy więc kompilator źle używa,memcpy
czy też piszę takie zadanie?Czy chodziło Ci o „Złożone” w liczbie zespolonej z częściami rzeczywistymi i urojonymi? Wydaje się to mało prawdopodobne, więc jeśli nie, musisz podać przykład, ponieważ „złożone” nie oznacza nic konkretnego w języku C.
Otrzymasz bezpośrednią kopię pamięci struktury; czy tego chcesz, zależy od struktury. Na przykład, jeśli struktura zawiera wskaźnik, obie kopie będą wskazywać te same dane. To może być to, czego chcesz, ale nie musi; to zależy od projektu twojego programu.
Aby wykonać „inteligentną” kopię (lub „głęboką” kopię), będziesz musiał zaimplementować funkcję, aby wykonać kopię. Może to być bardzo trudne do osiągnięcia, jeśli sama struktura zawiera wskaźniki i struktury, które również zawierają wskaźniki, a być może wskaźniki do takich struktur (być może to masz na myśli przez „złożone”), i jest trudne do utrzymania. Prostym rozwiązaniem jest użycie C ++ i zaimplementowanie konstruktorów kopiujących i operatorów przypisania dla każdej struktury lub klasy, a następnie każda z nich staje się odpowiedzialna za własną semantykę kopiowania, można użyć składni przypisania i jest ona łatwiejsza w utrzymaniu.
źródło