Ist es möglich, die Stapelzuweisung eines Objekts zu verhindern und nur zuzulassen, dass es auf dem Heap mit 'neu' versehen wird?Ist es möglich, die Stapelzuweisung eines Objekts zu verhindern und nur zuzulassen, dass es mit 'neu' instanziiert wird?
Antwort
Eine Möglichkeit wäre, die Konstruktoren privat zu machen und nur die Konstruktion über eine statische Methode zuzulassen, die einen Zeiger zurückgibt. Zum Beispiel:
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
private:
Foo();
Foo(const Foo&);
Foo& operator=(const Foo&);
};
+ 1 für die Erinnerung, um es nicht kopierbar zu machen. –
Oder noch besser eine statische Funktion, die ein std :: unique_ptr
** Verwandte Frage: ** [Wie verhindere ich die Zuweisung einer Klasse über den Operator 'new'? (Ich möchte sicherstellen, dass meine RAII-Klasse immer auf dem Stapel zugeordnet ist.)] (Http://stackoverflow.com/questions/124856/how-doi-i-prevent-a-class-from-being-alloated-) via-the-new-operator-id-artig) –
Sie könnten den Konstruktor private
erstellen und dann eine statische Factory-Methode public
zum Erstellen der Objekte bereitstellen.
Sie könnten eine Header-Datei erstellen, die eine abstrakte Schnittstelle für das Objekt zur Verfügung stellt und Fabrik-Funktionen, die Zeiger auf Objekte erstellt auf dem Heap zurück.
// Header file
class IAbstract
{
virtual void AbstractMethod() = 0;
public:
virtual ~IAbstract();
};
IAbstract* CreateSubClassA();
IAbstract* CreateSubClassB();
// Source file
class SubClassA : public IAbstract
{
void AbstractMethod() {}
};
class SubClassB : public IAbstract
{
void AbstractMethod() {}
};
IAbstract* CreateSubClassA()
{
return new SubClassA;
}
IAbstract* CreateSubClassB()
{
return new SubClassB;
}
Im Fall von C++ 11
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
Foo(const Foo &) = delete; // if needed, put as private
Foo & operator=(const Foo &) = delete; // if needed, put as private
Foo(Foo &&) = delete; // if needed, put as private
Foo & operator=(Foo &&) = delete; // if needed, put as private
private:
Foo();
};
Wie Scott Meyers in "Punkt 11: Gelöschte Funktionen an private undefinierte bevorzugen." sein Buch "Effective Modern C++" ist es besser, gelöschte Mitgliederfunktionen "public" zu deklarieren. --QUOTE-- "Per Konvention werden gelöschte Funktionen als' public', nicht als 'private' deklariert. Es gibt einen Grund dafür. Wenn Client-Code versucht, eine Member-Funktion zu verwenden, prüft C + + die Barrierefreiheit vor dem gelöschten Status versucht, eine gelöschte "private" -Funktion zu verwenden, beschweren sich einige Compiler nur über die Funktion "private", obwohl die Zugänglichkeit der Funktion nicht wirklich Einfluss darauf hat, ob sie verwendet werden kann. " –
--QUOTE-- "Es ist wichtig, dies bei der Überarbeitung von Legacy-Code zu berücksichtigen, um' private' und nicht definierte Mitgliedsfunktionen durch gelöschte zu ersetzen, da die neuen Funktionen 'public' im Allgemeinen zu besseren Fehlermeldungen führen. " –
Muss. Geben. Moar. Oben. Stimmen. – kevinarpe
Nachstehend ermöglicht öffentliche Konstruktoren und wird durch das Werfen zur Laufzeit Stapelzuordnungen stoppen. Hinweis thread_local
ist ein C++ 11-Schlüsselwort.
class NoStackBase {
static thread_local bool _heap;
protected:
NoStackBase() {
bool _stack = _heap;
_heap = false;
if (_stack)
throw std::logic_error("heap allocations only");
}
public:
void* operator new(size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new(size);
}
void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw() {
_heap = true;
return ::operator new(size, nothrow_value);
}
void* operator new(size_t size, void* ptr) throw() {
_heap = true;
return ::operator new(size, ptr);
}
void* operator new[](size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new[](size);
}
void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw() {
_heap = true;
return ::operator new[](size, nothrow_value);
}
void* operator new[](size_t size, void* ptr) throw() {
_heap = true;
return ::operator new[](size, ptr);
}
};
bool thread_local NoStackBase::_heap = false;
Ich glaube nicht, dass Sie '_stack' als Datenelement benötigen. Es sollte eine einfache Stapelvariable innerhalb des 'NoStackBase'-Konstruktors sein. –
Sie müssen den Destruktor auch nicht virtuell machen. Niemand kann eine abgeleitete Klasse trotzdem über eine 'NoStackBase' löschen. –
- 1. Bedeutung zu erklären, instanziiert wird, Initialisieren und Zuweisen eines Objekts
- 2. Ist es möglich zu verhindern, dass Laravel Model Events ausführt, wenn die Datenbank seeded wird?
- 3. Ist es möglich, alle Methoden und Eigenschaften aufzulisten, die über Invoke() eines [ADSI] -Objekts verfügbar sind?
- 4. ist es möglich, die Kamera nur in OpenGL zu bewegen, ohne die Szene neu zu zeichnen?
- 5. Ist es möglich zu verhindern, dass Selectize in das Dropdown-Menü konvertiert wird, wenn Maxitem = 1?
- 6. Ist es jemals möglich, dass die getPath-Methode eines java.net.URI-Objekts null zurückgibt? (Wenn ja, wann?)
- 7. Ist es möglich, die Beschreibung (String-Darstellung) eines Objekts in ein Objekt einer Klasse zu konvertieren?
- 8. Ist es möglich, Java-Methoden von Clojure neu zu definieren?
- 9. Ist es möglich, zu verhindern, dass das Bootstrap-Karussell beim Maus-Hover pausiert und automatisch weiterfährt?
- 10. Ist es möglich, eine Tabelle nur im Ruhezustand zu lesen?
- 11. Ist es möglich, eine Instanz eines Objekts in Java zu erstellen, ohne den Konstruktor aufzurufen?
- 12. Ist es möglich, gleichzeitige Builds in bestimmten Konfigurationen zu verhindern?
- 13. Ist es möglich, die Membervariable des Objekts zuzugreifen
- 14. Ist es möglich, die Transaktionalität eines Prozesses zu testen?
- 15. Ist es möglich, Symbole für eine EXE neu zu generieren?
- 16. Gibt es eine Möglichkeit, zu verhindern, dass Play automatisch neu geladen wird?
- 17. Ist es möglich, die Ansicht eines Fragments
- 18. Kann ich verhindern, dass eine Nicht-Template-Klasse instanziiert wird?
- 19. Ist es möglich, nur horizontales Scrollen zu verhindern, wenn Overflow-X ausgeblendet ist?
- 20. Ist es möglich, die Methode eines Objekts an eine Funktion zu senden?
- 21. Ist es möglich, die Größe eines xml zu berechnen, wenn es in XmlReader geladen wird?
- 22. Ist es möglich, die Hintergrundfarbe eines CMFCEditBrowseCtrl-Steuerelements zu ändern?
- 23. Ist es möglich, den Typ eines Objekts in einer Karte zu Castingzwecken zu speichern?
- 24. Ist es möglich, ein HTML-Element zu stylen, so dass es innere Stile nicht verletzen wird
- 25. Ist es möglich, Koroutinen nur mit LISP-Primitiven zu implementieren?
- 26. Ist es möglich nur Logmeldungen mit Log4J zu protokollieren
- 27. Ist es möglich, entfernte Android-APIs neu zu installieren?
- 28. Ist es möglich, eine Live-Instanz eines com-Objekts zwischen PowerShell-Sitzungen zu übergeben
- 29. Ist es möglich, Wordpress-Menü zu sperren, so dass nur Besitzer Admin es ändern können?
Die Rückseite, die auch für die Leser interessant sein könnten: http://stackoverflow.com/questions/10985/how-to-prevent-an-object-being-created-on-the-heap – kevinarpe