Ya. Kembali di masa lalu, kami baru saja menyebutnya "fungsi". Anda anak-anak hari ini dengan "ruang nama" Anda yang gila. Hei, turun dari halaman saya! <getar kepalan>
Vagrant
7
@ Jelas fungsi di dalam namespace masih merupakan fungsi. Fungsi yang termasuk kelas disebut metode. Jika ini adalah metode statis, Anda menjalankannya dengan cara yang sama seolah-olah itu adalah fungsi di dalam namespace.
48
5 tahun kemudian dan sekarang saya memihak @Vagrant. Pertanyaan yang konyol!
andrewrk
16
9 tahun kemudian dan sekarang saya memiliki bahasa pemrograman sendiri yang bahkan tidak memiliki kelas: ziglang.org
andrewrk
1
Kelas mirip wadah IMO (yang hanya memiliki metode statis) berguna dalam kasus-kasus tertentu.
AarCee
Jawaban:
272
Jika Anda mencari cara untuk menerapkan kata kunci "statis" ke suatu kelas, seperti yang Anda dapat di C # misalnya, maka Anda tidak akan dapat melakukannya tanpa menggunakan C ++ yang Dikelola.
Tapi sepertinya sampel Anda, Anda hanya perlu membuat metode statis publik pada objek BitParser Anda. Seperti itu:
BitParser.h
classBitParser{public:staticbool getBitAt(int buffer,int bitIndex);// ...lots of great stuffprivate:// Disallow creating an instance of this objectBitParser(){}};
BitParser.cpp
boolBitParser::getBitAt(int buffer,int bitIndex){bool isBitSet =false;// .. determine if bit is setreturn isBitSet;}
Anda dapat menggunakan kode ini untuk memanggil metode dengan cara yang sama seperti kode contoh Anda.
OJ, Anda memiliki kesalahan sintaksis . Kata kunci statis hanya boleh digunakan dalam definisi kelas, dan bukan dalam definisi metode.
andrewrk
90
Untuk memperjelas niat Anda dalam pendekatan ini, Anda juga dapat menggunakan konstruktor pribadi. private: BitParser() {}Ini akan mencegah siapa pun membuat instance.
Danvil
7
@MoatazElmasry safety thread merupakan masalah saat Anda berbagi status. Dalam implementasi di atas tidak ada status yang dibagikan, sehingga tidak ada masalah dengan keamanan utas ... kecuali Anda cukup bodoh untuk menggunakan statika di dalam fungsi-fungsi itu. Jadi ya, kode di atas aman untuk thread, jauhkan status gigih dari fungsi Anda dan Anda baik-baik saja.
OJ.
@MoatazElmasry Salah. Dua utas tidak dapat mengubah variabel lokal non-statis dalam fungsi statis.
OJ.
12
Jika C ++ 11, saya berpendapat lebih BitParser() = delete;baik menyampaikan maksud untuk menghapus konstruktor dengan benar (tidak hanya menyembunyikannya private).
Tetapi Anda harus ingat bahwa "kelas statis" adalah retasan dalam jenis bahasa seperti Java (misalnya C #) yang tidak dapat memiliki fungsi non-anggota, jadi mereka harus memindahkannya di dalam kelas sebagai metode statis.
Di C ++, yang Anda inginkan adalah fungsi non-anggota yang akan Anda deklarasikan di namespace:
Di C ++, namespace lebih kuat daripada kelas untuk pola "Java static method", karena:
metode statis memiliki akses ke simbol pribadi kelas
metode statis pribadi masih terlihat (jika tidak dapat diakses) untuk semua orang, yang melanggar enkapsulasi
metode statis tidak dapat dideklarasikan ke depan
metode statis tidak dapat kelebihan beban oleh pengguna kelas tanpa memodifikasi header perpustakaan
tidak ada yang dapat dilakukan dengan metode statis yang tidak dapat dilakukan lebih baik daripada fungsi non-anggota (mungkin teman) di namespace yang sama
ruang nama memiliki semantik sendiri (mereka dapat digabungkan, mereka bisa anonim, dll.)
dll.
Kesimpulan: Jangan menyalin / menempelkan pola Java / C # di C ++. Dalam Java / C #, polanya wajib. Tetapi dalam C ++, itu adalah gaya yang buruk.
Edit 2010-06-10
Ada argumen yang mendukung metode statis karena kadang-kadang, kita perlu menggunakan variabel anggota pribadi statis.
Saya agak tidak setuju, seperti yang ditunjukkan di bawah ini:
Pertama, myGlobal disebut myGlobal karena masih merupakan variabel pribadi global. Melihat sumber CPP akan menjelaskan bahwa:
// CPP
std::string Foo::myGlobal ;// You MUST declare it in a CPPvoidFoo::barA(){// I can access Foo::myGlobal}voidFoo::barB(){// I can access Foo::myGlobal, too}void barC(){// I CAN'T access Foo::myGlobal !!!}
Pada pandangan pertama, fakta bahwa fungsi barC gratis tidak dapat mengakses Foo :: myGlobal tampaknya merupakan hal yang baik dari sudut pandang enkapsulasi ... Ini keren karena seseorang yang melihat HPP tidak akan dapat (kecuali menggunakan sabotase) untuk mengakses Foo :: myGlobal.
Tetapi jika Anda melihatnya dengan seksama, Anda akan menemukan bahwa itu adalah kesalahan kolosal: Tidak hanya variabel pribadi Anda masih harus dinyatakan dalam HPP (dan karenanya, terlihat oleh seluruh dunia, meskipun bersifat pribadi), tetapi Anda harus mendeklarasikan dalam HPP yang sama semua (seperti dalam SEMUA) fungsi yang akan diizinkan untuk mengaksesnya !!!
Jadi menggunakan anggota statis pribadi seperti berjalan di luar telanjang dengan daftar kekasih Anda bertato di kulit Anda: Tidak ada yang diizinkan untuk menyentuh, tetapi semua orang dapat mengintip. Dan bonusnya: Setiap orang dapat memiliki nama-nama yang berwenang bermain dengan hadiah Anda.
private memang ... :-D
Solusi "Ruang nama anonim"
Ruang nama anonim akan memiliki keuntungan membuat hal-hal pribadi menjadi sangat pribadi.
Pertama, tajuk HPP
// HPPnamespaceFoo{void barA();}
Hanya untuk memastikan Anda berkomentar: Tidak ada deklarasi barB atau myGlobal yang tidak berguna. Yang berarti bahwa tidak ada yang membaca tajuk yang tahu apa yang tersembunyi di balik barA.
Kemudian, CPP:
// CPPnamespaceFoo{namespace{
std::string myGlobal ;voidFoo::barB(){// I can access Foo::myGlobal}}void barA(){// I can access myGlobal, too}}void barC(){// I STILL CAN'T access myGlobal !!!}
Seperti yang Anda lihat, seperti deklarasi "kelas statis", fooA dan fooB masih dapat mengakses myGlobal. Tapi tidak ada orang lain yang bisa. Dan tidak ada orang lain di luar CPP ini yang tahu fooB dan myGlobal bahkan ada!
Tidak seperti "kelas statis" yang berjalan telanjang dengan buku alamatnya bertato di kulitnya, namespace "anonim" sepenuhnya berpakaian , yang tampaknya AFAIK dienkapsulasi lebih baik.
Apakah itu penting?
Kecuali pengguna kode Anda penyabot (Aku akan membiarkan Anda, sebagai latihan, menemukan bagaimana seseorang dapat mengakses ke bagian pribadi dari public class menggunakan kotor hack perilaku-terdefinisi ...), apa privateyang private, bahkan jika itu terlihat di privatebagian kelas yang dinyatakan dalam header.
Namun, jika Anda perlu menambahkan "fungsi pribadi" lain dengan akses ke anggota pribadi, Anda masih harus mendeklarasikannya ke seluruh dunia dengan memodifikasi header, yang merupakan paradoks sejauh yang saya ketahui: Jika saya mengubah implementasi kode saya (bagian CPP), maka antarmuka (bagian HPP) TIDAK boleh berubah. Mengutip Leonidas: " Ini ENCAPSULASI! "
Edit 2014-09-20
Kapan kelas metode statis sebenarnya lebih baik daripada ruang nama dengan fungsi non-anggota?
Saat Anda perlu mengelompokkan fungsi-fungsi dan memberi makan grup itu ke templat:
namespace alpha
{void foo();void bar();}structBeta{staticvoid foo();staticvoid bar();};template<typename T>structGamma{void foobar(){
T::foo();
T::bar();}};Gamma<alpha> ga ;// compilation errorGamma<Beta> gb ;// ok
gb.foobar();// ok !!!
Karena, jika kelas bisa menjadi parameter templat, ruang nama tidak bisa.
GCC mendukung -fno-access-control, yang dapat digunakan dalam tes unit whitebox untuk mengakses anggota kelas pribadi. Itu tentang satu-satunya alasan saya bisa memikirkan untuk membenarkan menggunakan anggota kelas daripada global anonim / statis dalam implementasi.
Tom
8
@ Tom: Solusi lintas platform adalah dengan menambahkan kode berikut #define private publicdi header ... ^ _ ^ ...
paercebal
1
@ Tom: ngomong-ngomong, IMHO, bahkan mempertimbangkan pengujian unit, kontra "menunjukkan terlalu banyak barang" melebihi pro. Saya kira solusi alternatif adalah dengan meletakkan kode yang akan diuji dalam fungsi mengambil parameter yang diperlukan (dan tidak lebih) di utilitiesnamespace. Dengan cara ini, fungsi ini dapat diuji unit, dan masih tidak memiliki akses khusus ke anggota pribadi (seperti yang diberikan sebagai parameter pada panggilan fungsi) ...
paercebal
@ otak saya akan melompat ke atas kapal Anda, tapi saya punya satu pemesanan terakhir. Jika seseorang melompat pada Anda, namespacemereka tidak akan mendapatkan akses ke anggota Anda global, meskipun disembunyikan,? Jelas mereka harus menebak, tetapi kecuali Anda sengaja mengaburkan kode Anda, nama variabel cukup mudah ditebak.
Zak
@ Zak: Memang, mereka bisa, tetapi hanya dengan mencoba melakukannya di file CPP di mana variabel myGlobal dideklarasikan. Intinya lebih visibilitas daripada aksesibilitas. Di kelas statis, variabel myGlobal bersifat pribadi, tetapi masih terlihat. Ini tidak sepenting kelihatannya, tetapi masih, dalam DLL, menunjukkan simbol yang harus pribadi untuk DLL dalam header yang diekspor dapat menjadi canggung ... Di namespace, myGlobal hanya ada di file CPP (Anda bahkan bisa lebih jauh dan membuatnya statis). Variabel itu tidak muncul di header publik.
paercebal
63
Anda juga dapat membuat fungsi gratis di namespace:
Dalam beberapa kasus Anda mungkin ingin memiliki enkapsulasi data bahkan jika kelasnya sebagian besar "statis". Anggota kelas privat statis akan memberikan ini kepada Anda. Anggota Namespace selalu bersifat publik dan tidak dapat memberikan enkapsulasi data.
Torleif
Jika "anggota" var hanya dideklarasikan dan diakses dari file .cpp, itu lebih pribadi daripada var pribadi yang dinyatakan dalam file .h. BUKAN bahwa saya merekomendasikan teknik ini.
jmucchiello
3
@ Torleif: Anda salah. ruang nama lebih baik untuk enkapsulasi daripada anggota pribadi statis. Lihat jawaban saya untuk demonstrasi.
paercebal
1
ya tetapi di namespace Anda harus menjaga urutan fungsi, berbeda dengan kelas dengan anggota statis, misalnya void a () {b ();} b () {} akan menghasilkan kesalahan dalam namespace tetapi tidak di kelas dengan anggota statis
Moataz Elmasry
13
Jika Anda mencari cara untuk menerapkan kata kunci "statis" ke suatu kelas, seperti Anda dapat menggunakan C # misalnya
kelas statis hanyalah kompiler yang memegang Anda dan menghentikan Anda dari menulis metode / variabel instan.
Jika Anda hanya menulis kelas normal tanpa metode instance / variabel, itu adalah hal yang sama, dan ini adalah apa yang akan Anda lakukan di C ++
Bukan untuk mengeluh (terutama pada Anda), tetapi beberapa pegangan tangan penyusun untuk menjaga saya dari menulis atau memotong / menempel kata static200 kali akan menjadi hal yang baik.
3Dave
Setuju - tetapi kelas statis di C # tidak melakukan ini juga. Itu hanya gagal untuk mengkompilasi ketika Anda lupa menempelkan statis di sana :-)
Orion Edwards
Ya - cukup adil. Makro saya ditampilkan. Jujur, jika saya mendeklarasikan kelas sebagai statis, kompiler hanya akan membuang kesalahan jika saya mencoba untuk instantiate. Aturan yang mengharuskan saya mengulangi diri saya sendiri adalah menjengkelkan dan harus menjadi yang pertama melawan tembok ketika revolusi datang.
3Dave
11
Di C ++ Anda ingin membuat fungsi statis suatu kelas (bukan kelas statis).
Ubah: Dalam C ++, penentu statis atau eksternal hanya dapat diterapkan pada nama objek atau fungsi. Menggunakan specifier ini dengan deklarasi tipe adalah ilegal di C ++. Dalam C, penentu ini diabaikan ketika digunakan pada deklarasi tipe. Contoh:
staticstruct S {// valid C, invalid in C++int i;};
Dasar Pemikiran: Penentu kelas penyimpanan tidak memiliki arti apa pun saat dikaitkan dengan suatu jenis. Dalam C ++, anggota kelas dapat dideklarasikan dengan specifier kelas penyimpanan statis. Mengizinkan specifier kelas penyimpanan pada deklarasi tipe dapat membuat kode membingungkan bagi pengguna.
Dan suka struct, classjuga merupakan jenis deklarasi.
Hal yang sama dapat disimpulkan dengan berjalan di pohon sintaks di Lampiran A.
Seperti yang telah dicatat di sini, cara yang lebih baik untuk mencapai ini di C ++ mungkin menggunakan ruang nama. Tetapi karena tidak ada yang menyebutkan finalkata kunci di sini, saya memposting seperti apa persamaan langsung static classdari C # di C ++ 11 atau lebih baru:
classBitParser final
{public:BitParser()=delete;staticboolGetBitAt(int buffer,int pos);};boolBitParser::GetBitAt(int buffer,int pos){// your code}
Anda 'dapat' memiliki kelas statis di C ++, seperti yang disebutkan sebelumnya, kelas statis adalah salah satu yang tidak memiliki objek yang dipakai. Dalam C ++, ini dapat diperoleh dengan mendeklarasikan konstruktor / destruktor sebagai pribadi. Hasil akhirnya sama.
Dalam C # file.cs Anda dapat memiliki var pribadi di dalam fungsi publik. Ketika di file lain Anda dapat menggunakannya dengan memanggil namespace dengan fungsi seperti pada:
//Init the data (Link error if not done)intTheDataToBeHidden::_var1 =0;intTheDataToBeHidden::_var2 =0;//Implement the namespacenamespaceSharedData{voidSetError(constchar*Message,constchar*Title){//blah using TheDataToBeHidden::_var1, etc}voidDisplayError(void){//blah}}
OtherFile.h
#include"SharedModule.h"
OtherFile.cpp
//Call the functions using the hidden variablesSharedData::SetError("Hello","World");SharedData::DisplayError();
Satu kasus di mana ruang nama mungkin tidak begitu berguna untuk mencapai "kelas statis" adalah ketika menggunakan kelas-kelas ini untuk mencapai komposisi di atas warisan. Ruang nama tidak boleh menjadi teman kelas dan karenanya tidak dapat mengakses anggota pribadi kelas.
Salah satu (dari banyak) alternatif, tetapi yang paling (menurut saya) anggun (dibandingkan dengan menggunakan ruang nama dan konstruktor pribadi untuk meniru perilaku statis), cara untuk mencapai perilaku "kelas yang tidak dapat dipakai" dalam C ++ adalah dengan mendeklarasikan fungsi virtual murni dummy dengan privatepengubah akses.
Jika Anda menggunakan C ++ 11, Anda bisa bekerja lebih keras untuk memastikan bahwa kelas tidak diwarisi (untuk murni meniru perilaku kelas statis) dengan menggunakan finalspecifier dalam deklarasi kelas untuk membatasi kelas lain dari mewarisi itu .
// C++11 ONLYclassFoo final {public:staticint someMethod(int someArg);private:virtualvoid __dummy()=0;};
Meskipun terdengar konyol dan tidak masuk akal, C ++ 11 memungkinkan deklarasi "fungsi virtual murni yang tidak dapat ditimpa", yang dapat Anda gunakan bersama mendeklarasikan kelas finaluntuk secara murni dan sepenuhnya menerapkan perilaku statis karena ini menghasilkan resultan kelas untuk tidak diwariskan dan fungsi dummy untuk tidak diganti dengan cara apa pun.
// C++11 ONLYclassFoo final {public:staticint someMethod(int someArg);private:// Other private declarationsvirtualvoid __dummy()=0 final;};// Foo now exhibits all the properties of a static class
Jawaban:
Jika Anda mencari cara untuk menerapkan kata kunci "statis" ke suatu kelas, seperti yang Anda dapat di C # misalnya, maka Anda tidak akan dapat melakukannya tanpa menggunakan C ++ yang Dikelola.
Tapi sepertinya sampel Anda, Anda hanya perlu membuat metode statis publik pada objek BitParser Anda. Seperti itu:
BitParser.h
BitParser.cpp
Anda dapat menggunakan kode ini untuk memanggil metode dengan cara yang sama seperti kode contoh Anda.
Semoga itu bisa membantu! Bersulang.
sumber
private: BitParser() {}
Ini akan mencegah siapa pun membuat instance.BitParser() = delete;
baik menyampaikan maksud untuk menghapus konstruktor dengan benar (tidak hanya menyembunyikannyaprivate
).Pertimbangkan solusi Matt Price .
Apa yang Anda inginkan adalah, dinyatakan dalam semantik C ++, untuk menempatkan fungsi Anda (karena itu adalah fungsi) dalam namespace.
Edit 2011-11-11
Tidak ada "kelas statis" di C ++. Konsep terdekat adalah kelas dengan hanya metode statis. Sebagai contoh:
Tetapi Anda harus ingat bahwa "kelas statis" adalah retasan dalam jenis bahasa seperti Java (misalnya C #) yang tidak dapat memiliki fungsi non-anggota, jadi mereka harus memindahkannya di dalam kelas sebagai metode statis.
Di C ++, yang Anda inginkan adalah fungsi non-anggota yang akan Anda deklarasikan di namespace:
Mengapa demikian?
Di C ++, namespace lebih kuat daripada kelas untuk pola "Java static method", karena:
Kesimpulan: Jangan menyalin / menempelkan pola Java / C # di C ++. Dalam Java / C #, polanya wajib. Tetapi dalam C ++, itu adalah gaya yang buruk.
Edit 2010-06-10
Ada argumen yang mendukung metode statis karena kadang-kadang, kita perlu menggunakan variabel anggota pribadi statis.
Saya agak tidak setuju, seperti yang ditunjukkan di bawah ini:
Solusi "Anggota pribadi statis"
Pertama, myGlobal disebut myGlobal karena masih merupakan variabel pribadi global. Melihat sumber CPP akan menjelaskan bahwa:
Pada pandangan pertama, fakta bahwa fungsi barC gratis tidak dapat mengakses Foo :: myGlobal tampaknya merupakan hal yang baik dari sudut pandang enkapsulasi ... Ini keren karena seseorang yang melihat HPP tidak akan dapat (kecuali menggunakan sabotase) untuk mengakses Foo :: myGlobal.
Tetapi jika Anda melihatnya dengan seksama, Anda akan menemukan bahwa itu adalah kesalahan kolosal: Tidak hanya variabel pribadi Anda masih harus dinyatakan dalam HPP (dan karenanya, terlihat oleh seluruh dunia, meskipun bersifat pribadi), tetapi Anda harus mendeklarasikan dalam HPP yang sama semua (seperti dalam SEMUA) fungsi yang akan diizinkan untuk mengaksesnya !!!
Jadi menggunakan anggota statis pribadi seperti berjalan di luar telanjang dengan daftar kekasih Anda bertato di kulit Anda: Tidak ada yang diizinkan untuk menyentuh, tetapi semua orang dapat mengintip. Dan bonusnya: Setiap orang dapat memiliki nama-nama yang berwenang bermain dengan hadiah Anda.
private
memang ... :-DSolusi "Ruang nama anonim"
Ruang nama anonim akan memiliki keuntungan membuat hal-hal pribadi menjadi sangat pribadi.
Pertama, tajuk HPP
Hanya untuk memastikan Anda berkomentar: Tidak ada deklarasi barB atau myGlobal yang tidak berguna. Yang berarti bahwa tidak ada yang membaca tajuk yang tahu apa yang tersembunyi di balik barA.
Kemudian, CPP:
Seperti yang Anda lihat, seperti deklarasi "kelas statis", fooA dan fooB masih dapat mengakses myGlobal. Tapi tidak ada orang lain yang bisa. Dan tidak ada orang lain di luar CPP ini yang tahu fooB dan myGlobal bahkan ada!
Tidak seperti "kelas statis" yang berjalan telanjang dengan buku alamatnya bertato di kulitnya, namespace "anonim" sepenuhnya berpakaian , yang tampaknya AFAIK dienkapsulasi lebih baik.
Apakah itu penting?
Kecuali pengguna kode Anda penyabot (Aku akan membiarkan Anda, sebagai latihan, menemukan bagaimana seseorang dapat mengakses ke bagian pribadi dari public class menggunakan kotor hack perilaku-terdefinisi ...), apa
private
yangprivate
, bahkan jika itu terlihat diprivate
bagian kelas yang dinyatakan dalam header.Namun, jika Anda perlu menambahkan "fungsi pribadi" lain dengan akses ke anggota pribadi, Anda masih harus mendeklarasikannya ke seluruh dunia dengan memodifikasi header, yang merupakan paradoks sejauh yang saya ketahui: Jika saya mengubah implementasi kode saya (bagian CPP), maka antarmuka (bagian HPP) TIDAK boleh berubah. Mengutip Leonidas: " Ini ENCAPSULASI! "
Edit 2014-09-20
Kapan kelas metode statis sebenarnya lebih baik daripada ruang nama dengan fungsi non-anggota?
Saat Anda perlu mengelompokkan fungsi-fungsi dan memberi makan grup itu ke templat:
Karena, jika kelas bisa menjadi parameter templat, ruang nama tidak bisa.
sumber
#define private public
di header ... ^ _ ^ ...utilities
namespace. Dengan cara ini, fungsi ini dapat diuji unit, dan masih tidak memiliki akses khusus ke anggota pribadi (seperti yang diberikan sebagai parameter pada panggilan fungsi) ...namespace
mereka tidak akan mendapatkan akses ke anggota Andaglobal
, meskipun disembunyikan,? Jelas mereka harus menebak, tetapi kecuali Anda sengaja mengaburkan kode Anda, nama variabel cukup mudah ditebak.Anda juga dapat membuat fungsi gratis di namespace:
Di BitParser.h
Di BitParser.cpp
Secara umum ini akan menjadi cara yang disukai untuk menulis kode. Ketika tidak perlu untuk objek tidak menggunakan kelas.
sumber
kelas statis hanyalah kompiler yang memegang Anda dan menghentikan Anda dari menulis metode / variabel instan.
Jika Anda hanya menulis kelas normal tanpa metode instance / variabel, itu adalah hal yang sama, dan ini adalah apa yang akan Anda lakukan di C ++
sumber
static
200 kali akan menjadi hal yang baik.Di C ++ Anda ingin membuat fungsi statis suatu kelas (bukan kelas statis).
Anda kemudian dapat memanggil fungsi menggunakan BitParser :: getBitAt () tanpa membuat instance objek yang saya anggap sebagai hasil yang diinginkan.
sumber
Bisakah saya menulis sesuatu seperti
static class
?Tidak , menurut draft standar C ++ 11 N3337, Annex C 7.1.1:
Dan suka
struct
,class
juga merupakan jenis deklarasi.Hal yang sama dapat disimpulkan dengan berjalan di pohon sintaks di Lampiran A.
Sangat menarik untuk dicatat bahwa
static struct
itu legal di C, tetapi tidak berpengaruh: Mengapa dan kapan menggunakan struktur statis dalam pemrograman C?sumber
Seperti yang telah dicatat di sini, cara yang lebih baik untuk mencapai ini di C ++ mungkin menggunakan ruang nama. Tetapi karena tidak ada yang menyebutkan
final
kata kunci di sini, saya memposting seperti apa persamaan langsungstatic class
dari C # di C ++ 11 atau lebih baru:sumber
Anda 'dapat' memiliki kelas statis di C ++, seperti yang disebutkan sebelumnya, kelas statis adalah salah satu yang tidak memiliki objek yang dipakai. Dalam C ++, ini dapat diperoleh dengan mendeklarasikan konstruktor / destruktor sebagai pribadi. Hasil akhirnya sama.
sumber
Di Dikelola C ++, sintaks kelas statis adalah: -
... lebih baik terlambat daripada tidak sama sekali...
sumber
Ini mirip dengan cara C # melakukannya di C ++
Dalam C # file.cs Anda dapat memiliki var pribadi di dalam fungsi publik. Ketika di file lain Anda dapat menggunakannya dengan memanggil namespace dengan fungsi seperti pada:
Berikut cara menerapkan hal yang sama di C ++:
SharedModule.h
SharedModule.cpp
OtherFile.h
OtherFile.cpp
sumber
Tidak seperti bahasa pemrograman lain yang dikelola, "kelas statis" tidak memiliki arti dalam C ++. Anda dapat menggunakan fungsi anggota statis.
sumber
Satu kasus di mana ruang nama mungkin tidak begitu berguna untuk mencapai "kelas statis" adalah ketika menggunakan kelas-kelas ini untuk mencapai komposisi di atas warisan. Ruang nama tidak boleh menjadi teman kelas dan karenanya tidak dapat mengakses anggota pribadi kelas.
sumber
Salah satu (dari banyak) alternatif, tetapi yang paling (menurut saya) anggun (dibandingkan dengan menggunakan ruang nama dan konstruktor pribadi untuk meniru perilaku statis), cara untuk mencapai perilaku "kelas yang tidak dapat dipakai" dalam C ++ adalah dengan mendeklarasikan fungsi virtual murni dummy dengan
private
pengubah akses.Jika Anda menggunakan C ++ 11, Anda bisa bekerja lebih keras untuk memastikan bahwa kelas tidak diwarisi (untuk murni meniru perilaku kelas statis) dengan menggunakan
final
specifier dalam deklarasi kelas untuk membatasi kelas lain dari mewarisi itu .Meskipun terdengar konyol dan tidak masuk akal, C ++ 11 memungkinkan deklarasi "fungsi virtual murni yang tidak dapat ditimpa", yang dapat Anda gunakan bersama mendeklarasikan kelas
final
untuk secara murni dan sepenuhnya menerapkan perilaku statis karena ini menghasilkan resultan kelas untuk tidak diwariskan dan fungsi dummy untuk tidak diganti dengan cara apa pun.sumber