Frage

Weiß jemand, wie ich kann, in plattformunabhängigen C++ - code zu verhindern, dass ein Objekt auf dem heap erstellt?Das heißt, für ein Klasse "Foo", ich möchte verhindern, dass Benutzer, dies zu tun:

Foo *ptr = new Foo;

und nur dann es Ihnen ermöglichen, dies zu tun:

Foo myfooObject;

Hat jemand irgendwelche Ideen?

Cheers,

War es hilfreich?

Lösung

Nicks Antwort ist ein guter Ausgangspunkt, aber unvollständig, als Sie tatsächlich benötigen, um eine überlastung:

private:
    void* operator new(size_t);          // standard new
    void* operator new(size_t, void*);   // placement new
    void* operator new[](size_t);        // array new
    void* operator new[](size_t, void*); // placement array new

(Guter Programmierstil würde vorschlagen, Sie sollten auch die überlastung der delete und delete [] - Operatoren -- ich würde, aber da Sie nicht gehen, zu bekommen, nennt es nicht wirklich erforderlich.)

Pauldoo ist auch richtig, dass dies nicht überleben Aggregation auf Foo, obwohl es überleben Erben von Foo.Sie könnte eine template-meta-Programmierung Magie, um dies zu unterbinden, aber es wäre nicht immun gegen "böse-Benutzer" und damit ist wahrscheinlich nicht Wert, die Komplikation.Die Dokumentation darüber, wie es verwendet werden soll, und den code überprüfen, um sicherzustellen, dass es ordnungsgemäß verwendet wird, sind das nur ~100% Weg.

Andere Tipps

Sie könnten zu einer überlastung neu für Foo und machen Sie es privat.Dies würde bedeuten, dass der compiler meckern...es sei denn, Sie erstellen eine Instanz von Foo auf dem heap aus innerhalb von Foo.Fangen diesem Fall könnten Sie einfach nicht schreiben Foo neue Methode, und dann der linker würde Stöhnen über Undefinierte Symbole.

class Foo {
private:
  void* operator new(size_t size);
};

PS.Ja, ich weiß, das kann umgangen werden, leicht.Ich bin wirklich nicht zu empfehlen - ich denke, es ist eine schlechte Idee - ich war nur die Antwort auf die Frage!;-)

Ich weiß nicht, wie zu tun es zuverlässig und tragbare Art und Weise..aber..

Wenn das Objekt auf dem Stapel ist, dann könnten Sie in der Lage sein, zu behaupten, innerhalb des Konstruktors, dass der Wert von 'this' ist immer in der Nähe der stack-pointer.Es gibt eine gute chance, dass das Objekt auf dem Stapel, wenn dies der Fall ist.

Ich glaube, dass nicht alle Plattformen implementieren Ihre stacks in die gleiche Richtung, so möchten Sie vielleicht zu einem einmaligen test, wenn die app startet, um zu überprüfen, welche Art und Weise der stack wächst..Oder fudge:

FooClass::FooClass() {
    char dummy;
    ptrdiff_t displacement = &dummy - reinterpret_cast<char*>(this);
    if (displacement > 10000 || displacement < -10000) {
        throw "Not on the stack - maybe..";
    }
}

@Nick

Dies könnte umgangen werden, indem Sie eine Klasse erstellen, die sich aus oder Aggregate Foo.Ich denke, was ich empfehlen (obwohl nicht robust), würde immer noch funktionieren für abgeleitete und Aggregation von Klassen.

E. g:

struct MyStruct {
    Foo m_foo;
};

MyStruct* p = new MyStruct();

Hier habe ich erstellt eine Instanz von 'Foo' auf den Haufen, unter Umgehung Foo versteckte neuen Betreiber.

Da debug-Header überschreiben können die Betreiber neue Signatur, ist es am besten, um die ...Signaturen als die vollständige Beseitigung:

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

Könnten Sie deklarieren eine Funktion namens "operator new" in der Foo-Klasse, die würde, blockieren, den Zugang zu der normalen form von neu.

Ist dies die Art von Verhalten, die Sie wollen ?

Man könnte es erklären, wie eine Schnittstelle und die Umsetzung Klasse, die direkt aus Ihrem eigenen code.

dies kann verhindert werden, indem die Konstruktoren privat und bietet einen statischen member zu erstellen, die ein Objekt im Stapel

Class Foo
{
    private:
        Foo();
        Foo(Foo& );
    public:
        static Foo GenerateInstance() { 
            Foo a ; return a; 
        }
}

dadurch wird die Erstellung des Objekts immer im Stapel.

Nicht sicher, ob dies bietet jedem compile-Zeit-Chancen, aber haben Sie sich eine überlastung der 'new' - operator für Ihre Klasse?

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