Frage

Ich kopierte einige Delphi-code von einem Projekt zum anderen, und fand, dass es nicht kompilieren in das neue Projekt, obwohl es in den alten.Der code sieht ungefähr so aus:

procedure TForm1.CalculateGP(..)
const
   Price : money = 0;
begin
   ...
   Price := 1.0;
   ...
end;

Also in dem neuen Projekt, Delphi beschwert, dass "die linke Seite kann nicht zugewiesen werden" - verständlich!Aber dieser code kompiliert werden, in das alte Projekt.Also meine Frage ist, warum?Ist es ein compiler-switch und ermöglicht consts neu zugewiesen werden?Wie funktioniert das sogar arbeiten?Ich dachte, consts wurden ersetzt durch die entsprechenden Werte zur compile-Zeit?

War es hilfreich?

Lösung

Schalten Sie zuweisbare typisierte Konstanten auf.Projekt -> Optionen -> Compiler -> Zuweisbare typisierte Konstanten

Auch Sie können {$J+} oder {$WRITEABLECONST ON} die pas-Datei, die wohl besser, denn dann funktioniert es sogar, wenn Sie bewegen Sie die Datei auf ein anderes Projekt.

Andere Tipps

Typ abgeleitet Konstanten können nur Skalare Werte, d.h.Dinge wie integers, doubles, etc.Für diese Art von Konstanten, der compiler ist in der Tat ersetzen Sie die Konstante auf das symbol mit den Konstanten Wert, wenn es erfüllt Sie in Ausdrücken.

Typisierte Konstanten, auf der anderen Seite strukturiert werden kann, Werte - arrays und records.Diese Jungs brauchen tatsächlichen Lagerung in der ausführbaren Datei, d.h.Sie müssen Speicher für Sie reserviert, so dass, wenn das OS lädt das ausführbare Datei, die Wert der typisierte Konstante ist physisch, die sich auf einen Ort im Speicher.

Um zu erklären, warum, historisch, typisierte Konstanten, die in der frühen Delphi und dessen Vorgänger, Turbo Pascal, beschreibbar sind (und somit im wesentlichen initialisierte Globale Variablen), müssen wir gehen zurück zu den Tagen von DOS.

DOS läuft im real-Modus, in x86-Begriffe.Dies bedeutet, dass Programme, die direkten Zugriff auf den physischen Speicher, ohne MMU ein virtuelles-physikalische Zuordnungen.Wenn Programme haben Sie direkten Zugriff auf den Speicher, kein memory-Schutz wirksam ist.In anderen Worten, wenn es ist Speicher an beliebigen Adressen, es ist sowohl lesbar als auch beschreibbar im real-Modus.

Also, in einem Turbo-Pascal-Programm für DOS mit einer typisierten Konstante, deren Wert zugeordnet ist, an eine Adresse im Speicher zur Laufzeit, dass typisierte Konstanten beschrieben werden.Es gibt keine hardware-MMU immer in den Weg und verhindert, dass das Programm aus schreiben.Ähnlich, denn Pascal hat keine Vorstellung von 'const' Ness, die C++ hat, es gibt nichts in der Art system, um Sie zu stoppen.Viele Menschen nutzten diese, seit Turbo Pascal und Delphi nicht damals schon initialisierte Globale Variablen als Funktion.

Bewegen Sie sich auf Windows, es ist eine Schicht zwischen Speicher-Adressen und physischen Adressen:die memory management unit.Dieser chip übernimmt die Seite index (verschobene Maske), der die Speicheradresse, auf den Sie zugreifen möchten, und sucht die Attribute dieser Seite in Ihre Seite Tabelle.Diese Attribute umfassen lesbar, schreibbar, und für moderne x86-chips, non-executable flags.Mit dieser Unterstützung ist es möglich, Teile markieren, der .EXE oder .DLL mit Attributen wie, dass, wenn der Windows-loader lädt den ausführbaren Bild in den Speicher, es weist entsprechende Seite Parametern für Speicher-Seiten, die anzeigen auf disk-Seiten innerhalb dieser Abschnitte.

Wenn die 32-bit-Windows-version von der Delphi-compiler herum kam, es also Sinn zu machen, const-wie der Dinge wirklich const, da das OS auch hat diese Funktion.

  1. Warum:Da in früheren Versionen von Delphi die typisierte Konstanten Rückgangs waren standardmäßig zur Erhaltung der Kompatibilität mit älteren Versionen, bei denen Sie waren immer beschreibbar (Delphi 1 bis früh Pascal).
    Der Standard wurde nun geändert, um die Konstanten wirklich konstant...

  2. Compiler-Schalter:{$J+} oder {$J-} {$WRITEABLECONST ON} oder {$WRITEABLECONST OFF}
    Oder in den Projekt-Optionen für den compiler:überprüfen Sie zuweisbare typisierte Konstanten

  3. Wie es funktioniert:Wenn der compiler kann berechnen den value-at compile-Zeit, es ersetzt die const durch seinen Wert überall im code, sonst enthält es einen Zeiger auf einen Speicherbereich halten die Wert, die gemacht werden können beschreibbar oder nicht.
  4. siehe 3.

Wie Barry sagte, die Leute nutzten consts;Eine der Möglichkeiten, wie diese eingesetzt wurde, war für die Verfolgung der singleton-Instanzen.Wenn man sich einen klassischen singleton-Implementierung, würden Sie sehen :

  // Example implementation of the Singleton pattern.
  TSingleton = class(TObject)
  protected
    constructor CreateInstance; virtual;
    class function AccessInstance(Request: Integer): TSingleton;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    class function Instance: TSingleton;
    class procedure ReleaseInstance;
  end;

constructor TSingleton.Create;
begin
  inherited Create;

  raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]);
end;

constructor TSingleton.CreateInstance;
begin
  inherited Create;

  // Do whatever you would normally place in Create, here.
end;

destructor TSingleton.Destroy;
begin
  // Do normal destruction here

  if AccessInstance(0) = Self then
    AccessInstance(2);

  inherited Destroy;
end;

{$WRITEABLECONST ON}
class function TSingleton.AccessInstance(Request: Integer): TSingleton;
const
  FInstance: TSingleton = nil;
begin
  case Request of
    0 : ;
    1 : if not Assigned(FInstance) then
          FInstance := CreateInstance;
    2 : FInstance := nil;
  else
    raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]);
  end;
  Result := FInstance;
end;
{$IFNDEF WRITEABLECONST_ON}
  {$WRITEABLECONST OFF}
{$ENDIF}

class function TSingleton.Instance: TSingleton;
begin
  Result := AccessInstance(1);
end;

class procedure TSingleton.ReleaseInstance;
begin
  AccessInstance(0).Free;
end;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top