2009-12-21 7 views
14

Ich habe eine Anzahl von Klassen, für die ich die Heap-Zuweisung explizit verbieten möchte. Mir ist dieses Wochenende in den Sinn gekommen, dass ich den Operator einfach als privat (und nicht implementiert) deklarieren könnte ... Das führt natürlich zu Kompilierungsfehlern, wenn Sie versuchen, die Klasse zu ändern ... Meine Frage ist: Gibt es mehr dazu? Fehle ich etwas oder ist das eine gute Art zu tun, was ich will?Heap-Zuweisung explizit in C++ zu unterbinden

#include <stdio.h> 

class NotOnTheHeap 
{ 
public: 
    NotOnTheHeap() : foo(0) 
    { 
    } 

private: 
    void *operator new(size_t); 
    void operator delete(void*); 
    void *operator new[](size_t); 
    void operator delete[](void*); 

    int foo; 
}; 

class Heapable 
{ 
private: 
    NotOnTheHeap noth; 
}; 

int main(int argc, char* argv[]) 
{ 
    NotOnTheHeap noth; 

    Heapable* heapable = new Heapable; 

    return 0; 
} 
+2

Warum möchten Sie diese Klassen einschränken? – GManNickG

+3

@GManNickG Sie können es aus Leistungs- und Architekturgründen einschränken. Warum Sie Programmierer dazu bringen können, dies nicht zu tun, ist es gut, Dinge an Ort und Stelle zu haben, die dies unterstützen. So werden zufällige oder unbeabsichtigte Regelverletzungen abgefangen. Es ist wahrscheinlich einfacher, wenn Ihre Klasse selbst dies erzwingen könnte, anstatt zu versuchen, eine statische Analyse-Regel zu schreiben. – iheanyi

Antwort

11

Hängt davon ab, was Sie mit "Heap-Zuweisung explizit verbieten" meinen.

Wenn Sie nur eine direkte Zuordnung auf dem Heap verhindern wollen, d.h .:

NotOnTheHeap *n = new NotOnTheHeap(); 

es ist gut genug. Es verhindert jedoch nicht, dass Ihr Objekt im Allgemeinen auf dem Heap existiert.

Zum Beispiel wird es nicht verhindern, dass Menschen std::vector <NotOnTheHeap> verwenden, die Objekte aus Ihrer Klasse auf dem Haufen zuweisen wird.

Es wird auch nicht verhindern, dass Menschen eine NotOnTheHeap als Membervariable in einer anderen Klasse verwenden, die auf dem Heap zugeordnet ist.

+2

Die explizite Angabe der Zuweisungsfunktion ':: new A' funktioniert auch noch. –

+1

Ja, das habe ich erkannt ... Deshalb hatte ich im Beispiel "Heapable" ... Um zu zeigen, dass es indirekt noch auf dem Heap existieren könnte ... – dicroce

0

Können Sie nicht einfach die Implementierung des Operators neu eine Bestätigung (0) machen?

+22

Ich denke, ein Fehler bei der Kompilierung ist besser, als zuzulassen, dass der Code tatsächlich kompiliert und dann zur Laufzeit stirbt. –

+2

Kompilierungsfehler sind besser als behauptet. – dicroce

+1

Um etwas genauer zu sein, ist dies ein Link-Zeit-Fehler (der immer noch einem Laufzeitfehler vorzuziehen ist). –

1

Das wird meist erreichen, was Sie versuchen.

Was Ihre Lösung nicht abdeckt, ist in-place new, das sich auf dem Heap befinden kann oder auch nicht.

+1

Kann es erweitert werden, um die Platzierung neu zu decken? – dicroce

+2

Nein, Platzierung neu ist nicht ersetzbar. Es gibt einfach die Adresse zurück, die ihm gegeben wurde. – GManNickG

+0

Der Code, wie er in der Frage ist, deckt bereits die Platzierung neu ab: 'new (some_void_ptr) A' wird fehlschlagen.Es gilt nicht für :: :: new (some_void_ptr) A, denn wenn die Zuweisungsfunktion explizit angegeben wird, werden Klassenüberladungen nicht berücksichtigt (gilt für alle Placement-Formulare sowie Nicht-Placements, zB ':: new A') . Ich bin mir nicht sicher, warum GMan dies erwähnt, weil Sie 'A :: operator new (size_t, void *)' usw. erklären können, Sie können aber ':: operator new (size_t, void *)' nicht ersetzen, aber der Code ersetzt niemals den globalen ':: operator new (size_t)'. –

1

Sie können die Kopie oder sogar Standardkonstruktion und operator = etc für ein strengeres Szenario (einige Fälle von Einbetten von Werten oder Containerbenutzung) deaktivieren.

Das wird Sie jedoch aus einigen nützlichen Konstrukten herausbringen und Sie zwingen, Ihre eigene Semantik einzuführen (etwas sichtbarer in VM impls; Mangel/Induktion ähnlicher Operator und mehrdeutiger Äquivalenz/Gleichheits-Mechanismen). Sie werden wahrscheinlich auch ein paar Compiler-Warnungen sehen, es wird nicht den ganzen Weg gehen, aber wenn es einen Trost hat, kann es ein oder zwei Nutzen haben.

-2

Ergreifen Sie Scott Meyers effektives C++ und effektiveres C++ - er deckt diese Art von Sachen ab. Jeder C++ Programmierer sollte & diese Bücher lesen.

+0

Gutes Buch aber -1 für die Antwort auf die Frage. – ipapadop

Verwandte Themen