Frage

Ich überprüfe den Code eines Kollegen und sehe, dass er mehrere Konstanten im globalen Bereich definiert hat wie:

const string& SomeConstant = "This is some constant text";

Persönlich riecht dies für mich schlecht, weil sich die Referenz auf das bezieht, was ich annehme, ein "anonymer" Objekt ist, das aus dem angegebenen Zeichenanordnungsarray konstruiert ist.

Syntaktisch ist es legal (zumindest in VC ++ 7), und es scheint zu laufen, aber ich würde ihn wirklich lieber die & so entfernen lassen, dass es keine Unklarheit darüber gibt, was es tut.

Ist das wirklich sicher und legal und ich bin besessen? Hat das zu konstruierte temporäre Objekt eine garantierte Lebensdauer? Ich hatte immer angenommen, dass anonyme Objekte, die auf diese Weise verwendet wurden, nach dem Gebrauch zerstört wurden ...


Meine Frage könnte also auch auf eine anonyme Objektlebensdauer verallgemeinert werden. Bestimmt der Standard die Lebensdauer eines anonymen Objekts? Hätte es die gleiche Lebensdauer wie jedes andere Objekt in demselben Bereich? Oder wird es nur die Lebensdauer des Ausdrucks gegeben?


Auch wenn es als Einheimischer dies tun, ist es offensichtlich anders umgezogen:

class A
{
    string _str;

public:
    A(const string& str) :
        _str(str)
    {
        cout << "Constructing A(" << _str << ")" << endl;
    }

    ~A()
    {
        cout << "Destructing A(" << _str << ")" << endl;
    }
};

void TestFun()
{
    A("Outer");
    cout << "Hi" << endl;
}

Zeigt an:

Konstruktion a (äußere); Zerstörten a (äußere); Hi

War es hilfreich?

Lösung

Es ist völlig legal. Es wird erst dann zerstört, bis das Programm endet.

BEARBEITEN: Ja, es ist garantiert:

"Alle Objekte, die keine dynamische Speicherdauer haben, keine Gewindespeicherdauer haben und nicht lokal sind, haben eine statische Speicherdauer. Der Speicher für diese Objekte muss für die Dauer des Programms (3.6.2, 3.6.3) dauern. "

-- 2008 Arbeitsentwurf, Standard für die Programmiersprache C ++, § 3.7.1 p. 63

Wie Martin bemerkte, ist dies nicht die ganze Antwort. Der Standardentwurf Weitere Anmerkungen (§ 12.2, S. 250-1):

"Zeiträume des Klassentyps werden in verschiedenen Kontexten erstellt: Bindung eines Rvalue an eine Referenz (8.5.3) [...] Selbst wenn die Erstellung des temporären Objekts vermieden wird (12.8), müssen alle semantischen Beschränkungen wie bei respektiert werden Das temporäre Objekt wurde erstellt. [...] Temporäre Objekte werden als letzter Schritt zur Bewertung der Vollsexpression (1.9) zerstört, die (lexikalisch) den Punkt enthält, an dem sie erstellt wurden. [...] Es gibt zwei Kontexte in dem Zeiträume an einem unterschiedlichen Punkt als am Ende der Vollsexpression zerstört werden. [...] Der zweite Kontext besteht darin Vollständiges Objekt eines Unterobjekts, an das die Referenz gebunden ist, bleibt für die Lebensdauer der Referenz bestehen, außer wie unten angegeben. "

Ich habe in G ++ getestet, wenn Sie sich dadurch besser fühlen. ;))

Andere Tipps

Ja, es ist gültig und legal.

const string& SomeConstant = "This is some constant text";

// Is equivalent too:

const string& SomeConstant = std::string("This is some constant text");

So erstellen Sie ein temporäres Objekt.
Dieses temporäre Objekt ist an eine Konstant gebunden und hat somit seine Lebensdauer auf die Lebensdauer der Variablen, die es auch gebunden ist (dh länger als der Ausdruck, in dem es erzeugt wurde).

Dies ist gurantiert vom Standard.

Notiz:

Obwohl es legal ist. Ich würde es nicht benutzen. Die easistische Lösung würde darin bestehen, sie in eine konstante String umzuwandeln.

Verwendungszweck:

In dieser Situation ist die Variable im globalen Bereich für die gesamte Länge des Programms gültig. Es kann also verwendet werden, sobald die Ausführung Main () eingeht und nicht zugänglich ist, nachdem executiuon Main () beendet ist.

Obwohl es technisch gesehen ist, bevor dies vor diesem Gebrauch bei Konstruktoren/Zerstörern globaler Objekte verwendet wird, sollten Sie mit dem bekannten Problem der globalen variablen Initialisierungsreihenfolge gemildert werden.

Zusätzliche Gedanken:

Dies dagegen wird nicht unter dem Problem leiden:

char const* SomeConstant = "This is some constant text";

Und kann an jedem Punkt verwendet werden. Nur ein Gedanke.

Es mag legal sein, aber immer noch hässlich. Lasse die Referenz aus!

const string SomeConstant = "This is some constant text";

Es ist so legal wie hässlich.

Es ist legal, eine vorübergehende Variable mit a zu erweitern const Referenz, dies wird von Alexandrescu verwendet Scopegaurd Sehen Sie diese hervorragende Erklärung von Herb Sutter Calling an Ein Kandidat für die "wichtigsten const".

Davon abgesehen ist dieser spezielle Fall ein Missbrauch dieses Merkmals von C ++ und die Referenz sollte entfernt werden, um eine Ebene zu hinterlassen const string.

Indem Sie es als const deklarieren (was bedeutet, dass es nicht geändert werden kann) und es dann zu einer Referenz zu machen, die impliziert, dass jemand es ändern könnte, scheint zumindest eine schlechte Form zu sein. Wie ich sicher bin, sind globale Variablen schlecht und selten notwendig.

Okay, die Leute korrigieren mich, wenn ich am tiefen Ende bin, aber hier sind meine Schlussfolgerungen, die all Ihre hervorragenden Antworten hören:

A) Es ist syntaktisch und logisch legal, die & erweitert die Lebensdauer des Temps/Anonymos von jenseits der Ausdrucksebene bis zur Lebensdauer der Referenz. Ich habe dies in VC ++ 7 überprüft mit:

class A { 
    public: A() { cout << "constructing A" << endl; }
    public: ~A() { cout << "destructing A" << endl; }
};

void Foo()
{
    A();
    cout << "Foo" << endl;
}

void Bar()
{
    const A& someA = A();
    cout << "Bar" << endl;
}

int main()
{
    Foo();    // outputs constructing A, destructing A, Foo
    Bar();    // outputs constructing A, Bar, destructing A
    return 0;
}

B) Obwohl es legal ist, kann es zu einer gewissen Verwirrung hinsichtlich der tatsächlichen Lebensdauer führen, und die Referenz in diesen Fällen gibt Ihnen keinen Vorteil, sie als Nichtbeweis zu erklären. Daher sollte die Referenz wahrscheinlich vermieden werden und kann sogar zusätzlichen Raum sein . Da es keinen Nutzen gibt, ist es unnötige Verschleierung.

Vielen Dank für all die Antworten, es war eine sehr interessante Dikussion. Das lange und kurze und kurz: Ja, es ist syntaktisch legal, nein, es ist technisch nicht gefährlich, da die Lebenszeit verlängert wird, aber es fügt nichts hinzu und kann Kosten und Verwirrung hinzufügen. Warum also die Mühe machen?

Klang richtig?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top