Pertanyaan Bagaimana menerapkan konstruktor referensi?


Saya mencari cara agar konstruktor saya membuat referensi ke objek lain dengan cara ini:

Foo object1("File1");
Foo object2("File1");

Objek pertama dibuat secara normal. Objek kedua melihat bahwa sudah ada objek yang menggunakan parameter "File1" dan menjadikan dirinya referensi ke objek pertama. Saya tahu ini mungkin tidak secara langsung mungkin untuk melakukan ini dengan cara ini. Saya menyimpan vektor statis Foo * untuk melacak objek yang dialokasikan.

Saya tahu bahwa saya dapat membuat semua anggota dari pointer kelas dan untuk kasus pertama membuat (Baru) mereka. Dalam kasus kedua, saya tidak akan membuatnya dan mengarahkannya ke objek pertama. Juga objek kedua dijamin memiliki masa hidup yang lebih pendek dari yang pertama.

Jadi, adakah cara mudah / elegan untuk melakukan ini?

EDIT: Terima kasih atas semua solusi hebatnya. Saya suka semuanya, tapi saya hanya bisa menggunakannya. Saya akan menyimpan semua pengetahuan ini untuk referensi di masa mendatang.

Saya memilih static map <string, FooObject*> larutan. Pada awalnya saya pikir itu bodoh, tetapi setelah ditinjau lebih lanjut, itu menarik bagi saya sebagai elegan.

Satu-satunya tambahan yang bisa saya lihat sekarang adalah menambahkan penghitung tautan ke FooObject. Dengan cara ini di konstruktor Foo saya dapat meningkatkan penghitung tautan. Dalam destruktor, kurangi penghitung. Jika penghitung kemudian nol, keluarkan dari peta. Dengan cara ini tidak ada kebocoran memori, dan benda-benda bisa dihancurkan dalam urutan apa pun. Saya kira metodologi ini adalah esque shared_ptr. Kredit masuk ke @Travis untuk ini.

Terima kasih, James.


5
2018-03-10 16:16


asal


Jawaban:


Coba gunakan static map<string, object*> sebagai variabel di mana objek adalah sisa dari kelas yang Anda butuhkan.


6
2018-03-10 16:18



Anda dapat menggunakan pengelola sumber daya. Ini harus memiliki antarmuka seperti ini:

class ResourceManager
{
public:
   Foo* GetFoo(some id type, maybe file name);
   void ReleaseFoo(Foo* fooObj);
}

Di dalamnya akan mencari jika ada Foo * objek yang menggunakan id yang sama seperti id baru dan jika ini keluar maka akan mengembalikan Foo lama * objek lain itu akan membuat objek baru tipe Foo *. Ini juga akan menghitung jumlah objek Foo * untuk setiap id. Ketika fungsi Rilis disebut itu akan mengurangi jumlah id itu (yang mengidentifikasi dalam objek yang unik) dan jika 0 itu akan menghapus objek.

Ini adalah cara paling sederhana untuk melakukan ini. Anda dapat menjalankannya di utas lain untuk lebih dari satu jenis sumber daya dan hal-hal lain, tetapi ini adalah gagasan dasar.


1
2018-03-10 16:24



Ini kedengarannya mungkin seperti kelas terbang http://en.wikipedia.org/wiki/Flyweight_pattern

Jika Anda berada dalam lingkungan single-threaded Anda hanya bisa memiliki statis std::map<std::string, ObjectImpl*> di kelas Anda dan digunakan oleh konstruktor Anda. Anda akan menggunakan pola pimpl untuk menyimpan implementasi aktual dan ketika objek dibuat memeriksa untuk melihat apakah implementasi sudah tersedia. Jika ya, aturlah penunjuk dengan segera. Jika Anda perlu membersihkan ketika tidak ada referensi yang tersisa, Anda dapat menambahkan kode tambahan untuk menangani itu juga.


0
2018-03-10 16:25



Anda hanya perlu metode pabrik yang mengembalikan Foos dan selalu menyebutnya mengharapkan referensi. Kemudian Anda menyimpannya dalam peta statis dan Anda memeriksanya ketika Anda ditanya.

Foo &file = getmefile("file1");
Foo &file2 = getmefile("file1");

Foo &getmefile(string filename){
   if (foos.find(filename) == foos.end() ) {
        foos[filename] = Foo(filename);
   }
   return foos[filename];
}

0
2018-03-10 16:26