Cara untuk mencegah suatu objek yang dibuat di heap?

Tidak ada yang tahu bagaimana saya dapat, di platform-independen C++ code mencegah suatu objek yang diciptakan pada tumpukan? Artinya, untuk kelas "Anu", saya ingin mencegah pengguna dari melakukan hal ini:

Foo *ptr = new Foo;

dan hanya memungkinkan mereka untuk melakukan hal ini:

Foo myfooObject;

Apakah ada yang punya ide?

Cheers,

Mengomentari pertanyaan (2)
Larutan

Nick's answer adalah titik awal yang baik, tapi tidak lengkap, karena anda benar-benar perlu berlebihan:

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

(Praktek coding yang baik akan menunjukkan anda juga harus membebani menghapus dan menghapus[] operator-aku mau, tapi karena mereka're tidak akan mendapatkan menyebutnya isn't benar-benar diperlukan.)

Pauldoo adalah juga benar bahwa ini doesn't bertahan menggabungkan pada Foo, meskipun tidak bertahan mewarisi dari Foo. Anda bisa melakukan beberapa template meta-pemrograman sihir untuk MEMBANTU mencegah hal ini, tapi itu tidak akan menjadi kebal terhadap "kejahatan pengguna" dan dengan demikian mungkin tidak sepadan dengan komplikasi. Dokumentasi tentang bagaimana hal itu harus digunakan, dan code review untuk memastikan hal ini digunakan dengan benar, ini adalah satu-satunya ~100% jalan.

Komentar (3)

Anda bisa overload baru untuk Foo dan membuatnya pribadi. Ini berarti bahwa compiler akan mengerang... kecuali anda're menciptakan sebuah instance dari Foo di tumpukan dari dalam Foo. Untuk menangkap hal ini, anda hanya bisa tidak menulis Foo's metode baru dan kemudian linker akan mengeluh tentang simbol tidak terdefinisi.

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

PS. Ya, aku tahu ini dapat dielakkan dengan mudah. I'm benar-benar tidak merekomendasikan itu - saya pikir itu's merupakan ide yang buruk - aku hanya menjawab pertanyaan! ;-)

Komentar (0)

Saya don't tahu bagaimana untuk melakukannya andal dan portabel jalan.. tapi..

Jika objek pada stack maka anda mungkin dapat untuk menegaskan dalam constructor bahwa nilai 'ini' selalu dekat dengan stack pointer. Ada's kesempatan baik bahwa objek akan di stack jika hal ini terjadi.

Saya percaya bahwa tidak semua platform melaksanakan tumpukan mereka di arah yang sama, sehingga anda mungkin ingin melakukan satu kali uji ketika aplikasi mulai verifikasi yang menumpuk tumbuh.. Atau melakukan beberapa fudge:

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

@Nick

Hal ini bisa disiasati dengan menciptakan kelas yang berasal dari atau agregat Foo. Saya pikir apa yang saya sarankan (sementara tidak kuat) akan tetap bekerja untuk diturunkan dan menggabungkan kelas-kelas.

E. g:

struct MyStruct {
    Foo m_foo;
};

MyStruct* p = new MyStruct();

Di sini saya telah menciptakan sebuah instance dari 'Foo' di heap, melewati Foo's tersembunyi di operator baru.

Komentar (1)

Karena debug header dapat menimpa operator baru tanda tangan, itu adalah yang terbaik untuk menggunakan ... tanda tangan sebagai obat lengkap:

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

hal ini dapat dicegah dengan membuat konstruktor pribadi dan memberikan anggota statis untuk membuat objek dalam stack

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

ini akan membuat kreasi dari objek selalu dalam stack.

Komentar (0)

Anda bisa menyatakan itu sebagai interface dan kontrol pelaksanaan kelas yang lebih langsung dari kode anda sendiri.

Komentar (0)

Anda dapat menyatakan suatu fungsi yang disebut "operator baru" dalam Foo kelas yang akan memblokir akses ke bentuk normal baru.

Ini adalah jenis perilaku yang anda inginkan ?

Komentar (0)

Tidak yakin apakah ini menawarkan setiap waktu kompilasi peluang, tapi apakah anda melihat overloading 'baru' operator untuk kelas anda?

Komentar (0)