Warum muss main deklariert werden, als ob es eine externe Verbindung hat?
Warum sollte es nicht statisch sein?
Was ist mit externer Verknüpfung gemeint?
Weil du die Startup-Dateien mit deinem Programm verknüpfst, das (normalerweise) Assembler-Code enthält, der deine Hauptdatei aufruft. Wenn main statisch wäre, könnte dieser Code main nicht aufrufen.
external linkage
bedeutet, dass andere so genannte translation-units
Ihr extern erklärtes Symbol in einer eigenen Übersetzungseinheit sehen können. Also, Ihr Haupt ist extern, und es wird einen Eintrag in seiner Übersetzungseinheits-Symboltabelle haben, die seine Adresse angibt. Andere Übersetzungseinheiten können dann zu dieser Adresse springen, wenn sie main anrufen möchten.
static linkage
bedeutet, dass Ihr Symbol streng lokal übersetzt ist. Dies bedeutet, dass andere translation units
dieses Symbol nicht sehen können. Daher können Symbole mit statischer Verknüpfung in verschiedenen Übersetzungseinheiten mehrmals auftreten und sie werden nicht miteinander kollidieren, weil sie lokal sind.
Bearbeiten : Dateien, die vom Compiler aus Übersetzungseinheiten generiert werden, sind im Allgemeinen für diesen bestimmten Compiler spezifisch. Für gcc unter Linux wird oft das ELF-Objektformat verwendet. Sie können seine Symboltabelle mit readelf -sW <file>.o
(einfache Testdatei unten) anzeigen:
test.c
%Vor%Hier ist die Ausgabe von readelf:
%Vor% Sie sehen die Hauptfunktion und eine statische foo-Funktion, die von main aufgerufen wird. Außerdem gibt es eine aufgerufene Funktion, die nicht in der Datei definiert ist, sondern in einer anderen Objektdatei definiert ist. Da die Objektdatei noch nicht endgültig verknüpft wurde, sind den Funktionen noch keine endgültigen Adressen zugewiesen. Nach dem letzten Link werden diese in der ausführbaren Datei angeordnet und Adressen zugewiesen. Die Objektdatei enthält Einträge für Aufrufe von noch nicht definierten Funktionen, so dass bei der Verknüpfung der Datei bei diesen Aufrufanweisungen die endgültigen Adressen gespeichert werden können ( readelf -r <file>.o
):
Der eigentliche Startpunkt des Codes ist in der C-Laufzeitbibliothek verborgen. Diese Laufzeitbibliothek ruft Ihre main () Routine auf. Damit der Linker den C RTL-Aufruf mit Ihrer main () - Funktion verbinden kann, muss er außerhalb der Datei sichtbar sein.
Externe Verknüpfung ist nur das: es bedeutet, dass der fragliche Name als Teil der Exporte der Objektdatei sichtbar ist. Die Aufgabe des Linkers besteht darin, alle Importe und Exporte so zu verknüpfen, dass keine ausstehenden Importe mehr vorhanden sind.
Geben Sie eine neue Instanz von Person zurück, die eine Kopie von %code% anstelle von %code% selbst in Get () ist. Sie benötigen eine Methode, um eine Tiefenkopie eines Person-Objekts zu erstellen. Dadurch werden sie nicht nur gelesen, sondern sie unterscheiden sich von denen in der ursprünglichen Liste.
%Vor%Tatsächlich ist %code% bereits Readtonly . Das bedeutet, dass Sie keine Elemente in der zugrunde liegenden Sammlung durch andere Elemente ersetzen können. Das heißt, Sie können die Referenzen nicht auf die %code% -Objekte ändern, die in der Sammlung enthalten sind. Der Typ %code% ist jedoch nicht schreibgeschützt, und da es sich um einen Referenztyp handelt (d. H. Ein %code% ), können Sie seine Member über die Referenz ändern.
Es gibt zwei Lösungen:
Sie können einen Deepclone für jedes Element in der Liste erstellen und niemals Referenzen auf Ihre ursprünglichen Elemente zurückgeben.
%Vor%%code% ist nur gelesen
%code% ist eine neue Kollektion, die nicht von %code% abhängig ist.
Der Fehler, den Sie gemacht haben, ist, dass Sie diese Zeile gedacht haben
%code%
würde nur eine der Listen ändern, wenn Sie in Wirklichkeit das Objekt %code% ändern.
Die beiden Kollektionen sind unterschiedlich, sie haben zufällig dieselben Artikel.
Um zu beweisen, dass sie unterschiedlich sind, versuche, Elemente aus einer der Listen hinzuzufügen und zu entfernen, und du wirst sehen, dass die andere nicht betroffen ist.
Zunächst einmal ist Ihre Liste in Ihrer Klasse öffentlich, sodass niemand daran gehindert wird, direkt auf die Liste zuzugreifen.
Zweitens würde ich IEnumerable implementieren und das in meiner GetEnumerator-Methode
zurückgeben %Vor%Wenn Ihr Personenobjekt ein reales Objekt ist, sollten Sie eine unveränderbare Version in Erwägung ziehen.
%Vor%Auf diese Weise ist es nicht möglich, den Inhalt der einmal erstellten Instanz zu ändern. Daher ist es nicht wichtig, dass vorhandene Instanzen in mehreren Listen wiederverwendet werden.
Warum sind die Listen %code% und %code% in der Methode %code% des folgenden Codes auf die selbe Sammlung?
%Vor%Können wir dieses Verhalten ändern, ohne den Rückgabetyp von %code% zu ändern?
Danke
Sie verweisen nicht auf dieselbe .Net-Sammlung, sondern auf dieselben %code% -Objekte. Die Linie:
%Vor%kopiert alle Person-Elemente von %code% in die Liste %code% . Das Wort "Kopien" bedeutet hier Kopien der Referenzen. Also, Ihre Liste und %code% zeigen zufällig auf die gleichen %code% -Objekte.
%code% ist per Definition immer schreibgeschützt. Die Objekte darin können jedoch wie in diesem Fall veränderbar sein.