Wir testen eine Bibliothek unter C ++ 11 (dh -std=c++11
). Die Bibliothek verwendet auto_ptr
und dieses Muster:
Foo* GetFoo()
{
autoptr<Foo> ptr(new Foo);
// Initialize Foo
ptr->Initialize(...);
// Now configure remaining attributes
ptr->SomeSetting(...);
return ptr.release();
}
C ++ 11 ist veraltet auto_ptr
, daher möchten wir uns davon entfernen.
Der Code unterstützt jedoch sowohl C ++ 03 als auch C ++ 11 auto_ptr
. Erwähnenswert ist auch, dass die Bibliothek keine externen Abhängigkeiten aufweist. Es verwendet C ++ 03; und verwendet keine Autotools, Cmake, Boost, ...
Wie sollen wir mit den Designänderungen umgehen, um uns von auto_ptr
C ++ 11 zu entfernen, während die Kompatibilität mit C ++ 03 erhalten bleibt?
auto_ptr
einige der Bereiche vorhanden (dhstd::auto_ptr
müssen sie vorhanden sein oder kann der Smart Pointer aus einem anderen Namespace abgerufen werden?Foo::Initialize
inFoo::Foo
.Antworten:
In den meisten Hinsichten wurde das
std::unique_ptr
als Ersatz (aber sicherer) gemachtstd::auto_ptr
, so dass nur sehr wenige (wenn überhaupt) Codeänderungen erforderlich sein sollten, außer (wie Sie verlangen), den Code entwederunique_ptr
oder zu verwendenauto_ptr
.Es gibt einige Möglichkeiten, dies zu tun (und jede hat ihre eigenen Listenkompromisse). Angesichts des bereitgestellten Codebeispiels würde ich eine der beiden ersten Optionen bevorzugen .
Option 1
Kompromisse;
auto_ptr
Namen in den globalen Namespace ein. Sie können dies abschwächen, indem Sie festlegen, dass es sich um Ihren eigenen "privaten" Namespace handeltauto_ptr
wird komplett entfernt), können Sie einfacher suchen und ersetzenOption 2
Kompromisse;
auto_ptr
Code muss auf so etwas wie geändert werdenmy_ptr<T>::ptr
Option 3
Etwas umstritten, aber wenn Sie bereit sind, die Einschränkungen einer
std
Klasse als Basis in Kauf zu nehmenKompromisse;
Option 4
Schließen Sie die Zeiger in eine neue Klasse ein und aggregieren Sie die erforderlichen Funktionen für das Mitglied
Kompromisse;
quelle
tr1
Namespace Nr länger da sein (ich benutze libc ++ und nicht libstdc ++). Ich weiß, dass tr1 nicht normativ war, aber ich kann nirgendwo im Entwurf (hier) feststellen, dass die Dateien<tr1/...>
überhaupt vorhanden sein mussten. Infact erwähnt, dass sie sich nur im Header<memory>
usw. befinden, nur imtr1
Namespace.CXX=...
).c++ -v -std=c++11 -x c++ - < /dev/null
. Ichgrep'd
die Include - Verzeichnisse , die abgeladen wurden, und sie nicht enthaltenunique_ptr
.Option 5: Direkter Alias.
Kompromisse:
Bei neueren Sprachversionen, AKA C ++ 11 und höher, wird Ihr Alias-Typ dem richtigen Smart Pointer zugeordnet. Jeder Benutzercode, der tatsächlich von APIs abhängt, die für std :: auto_ptr spezifisch sind, wird vom Compiler markiert. Dies ist die ultimative Garantie dafür, dass er wirklich repariert wird.
Im Legacy-C ++ 03-Modus ist der Typ-Alias ein Makro. Dies ist grob, aber die resultierende Syntax
MyPtr<T>
ist im Rest des Codes identisch mit der von C ++ 11.Sie müssen alle auto_ptr-Variablen
MyPtr
in suchen und ändern , um dies einzurichten.quelle