Kapan Anda harus menggunakan kelas vs struct di C ++?

951

Dalam skenario apa lebih baik menggunakan structvs a classdi C ++?

Alan Hinchcliffe
sumber
48
Ini tidak hanya berlaku untuk C ++, tetapi untuk bahasa apa pun yang menyediakan struct dan kelas.
Jason Bunting
3
Saya masih tidak setuju - saya mendekati pertanyaan ini secara semantik. Mungkin ada beberapa perbedaan teknis, tetapi secara semantik tidak. Structs sangat berguna untuk membuat tipe nilai, kelas tidak.
Jason Bunting
4
Saya percaya bahwa tidak ada alasan serius untuk menggunakan struct di C ++. Bagiku struct adalah "fitur" redundan C ++ yang hanya ada untuk kompatibilitas dengan C, seperti typedefs. Ini tidak akan ada jika C ++ pada awalnya tidak diperlakukan sebagai ekstensi ke C, dan dirancang dari awal, seperti Java. Secara umum, saya menemukan bahwa banyak hal aneh tentang C ++ ada hubungannya dengan kompatibilitas C.
Kostas
5
Struct - Untuk POD (data lama biasa) dan semua aksesibilitas anggota bersifat publik. Kelas - Ketika Anda membutuhkan enkapsulasi yang lebih baik dan membutuhkan fungsi anggota untuk bekerja dengan status kelas.
Navaneeth KN
4
Ini benar hanya dengan konvensi. Tidak ada perbedaan, kecuali enkapsulasi default.
Dave Hillier

Jawaban:

806

Perbedaan antara a classdan a structdalam C ++ adalah bahwa struct memiliki publicanggota dan pangkalan default dan kelas memiliki privateanggota dan pangkalan default . Baik kelas dan struct dapat memiliki campuran public, protecteddan privateanggota, dapat menggunakan warisan dan dapat memiliki fungsi anggota.

Saya akan merekomendasikan menggunakan struct sebagai struktur data lama-polos tanpa fitur seperti kelas, dan menggunakan kelas sebagai struktur data agregat dengan privatedata dan fungsi anggota.

Commodore Jaeger
sumber
100
Sebuah struct tanpa pengubah atau metode disebut struct POD, yang ada sebagai antarmuka yang kompatibel dengan C library karena dijamin seharusnya diletakkan seolah-olah itu adalah struct C. Terlepas dari satu pengecualian ini, satu-satunya perbedaan adalah seperti yang dinyatakan.
workmad3
26
@ workmad3: Namanya menyesatkan, tetapi 9/4 (C ++ 03) mengatakan: "Sebuah POD-struct adalah kelas agregat yang tidak memiliki anggota data non-statis tipe non-POD-struct, non-POD-union (atau array jenis seperti itu) atau referensi, dan tidak memiliki operator penugasan salinan yang ditentukan pengguna dan tidak ada destruktor yang ditentukan pengguna. " Tidak ada batasan untuk menggunakan kunci kelas "struct" dan tidak ada batasan untuk menggunakan "publik" (lihat 8.5.1 / 1 untuk persyaratan agregat). Ini bukan perbedaan antara "struct" dan "class".
5
Penggunaan "agregat" Anda dapat disalahpahami, mengingat definisi standar. :)
3
Menurut buku "Prinsip dan Praktek" Stroustrup: "struct harus digunakan terutama di mana anggota dapat mengambil nilai apa pun" (yaitu di mana tidak ada kelas invarian yang bermakna dapat didefinisikan)
antibodi
6
Tentu saja Anda dapat menggunakan kelas saat berinteraksi dengan C. Tidak ada perbedaan antara kelas dan struct. Struct adalah kelas; hanya akses standar yang dialihkan dari pribadi ke publik.
Sebastian Mach
230

Seperti yang dicatat semua orang, hanya ada dua perbedaan bahasa yang sebenarnya:

  • structdefault untuk akses publik dan classdefault untuk akses pribadi.
  • Saat mewarisi, structbawaan ke publicwarisan dan classbawaan ke privatewarisan. (Ironisnya, seperti halnya banyak hal dalam C ++, standarnya adalah mundur: publicpewarisan adalah pilihan yang lebih umum, tetapi orang jarang menyatakan structhanya untuk menghemat mengetik " public" kata kunci.

Tetapi perbedaan nyata dalam praktik adalah antara a class/ structyang menyatakan konstruktor / destruktor dan yang tidak. Ada jaminan tertentu untuk tipe POD "data lama", yang tidak lagi berlaku setelah Anda mengambil alih konstruksi kelas. Agar perbedaan ini jelas, banyak orang yang sengaja hanya menggunakan structs untuk tipe POD, dan, jika mereka akan menambahkan metode apa pun, gunakan classes. Perbedaan antara dua fragmen di bawah ini tidak ada artinya:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(Kebetulan, inilah utas dengan beberapa penjelasan yang bagus tentang apa sebenarnya arti "tipe POD": Apa tipe POD dalam C ++? )

quark
sumber
Contoh yang bagus mengenai perbedaan warisan: di sini .
Liran Orevi
8
Apakah Anda menggunakan structatau classtidak memiliki kaitan apakah objek Anda adalah POD atau apakah Anda harus mendefinisikan copy constructor / destructor. Fungsi anggota juga tidak ada hubungannya dengan sesuatu yang menjadi POD. Ketika saya membaca kembali apa yang Anda tulis, saya melihat Anda tidak menyarankan sebaliknya, tetapi kata-kata saat ini membingungkan
David Stone
1
@ DavidvidStone Pada dasarnya, struct POD seharusnya dijamin kompatibel dengan kode C, dan karenanya pada dasarnya seharusnya dirancang sebagai struct gaya-C.
Justin Time - Pasang kembali Monica
3
Bagian "perbedaan nyata" dari jawaban ini benar-benar salah.
juanchopanza
178

Ada banyak kesalahpahaman dalam jawaban yang ada.

Keduanya classdan structmendeklarasikan kelas.

Ya, Anda mungkin harus mengatur ulang akses Anda memodifikasi kata kunci di dalam definisi kelas, tergantung pada kata kunci yang Anda gunakan untuk mendeklarasikan kelas.

Tapi, di luar sintaks, satu - satunya alasan untuk memilih satu dari yang lain adalah konvensi / gaya / preferensi.

Beberapa orang suka tetap menggunakan structkata kunci untuk kelas tanpa fungsi anggota, karena definisi yang dihasilkan "terlihat seperti" struktur sederhana dari C.

Demikian pula, beberapa orang suka menggunakan classkata kunci untuk kelas dengan fungsi dan privatedata anggota, karena ia mengatakan "kelas" di atasnya dan karenanya terlihat seperti contoh dari buku favorit mereka tentang pemrograman berorientasi objek.

Kenyataannya adalah bahwa ini sepenuhnya terserah Anda dan tim Anda, dan itu tidak akan membuat perbedaan apa pun bagi program Anda.

Dua kelas berikut ini benar-benar setara dalam segala hal kecuali namanya:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Anda bahkan dapat mengganti kata kunci saat mendeklarasikan ulang:

class Foo;
struct Bar;

(walaupun ini memecah Visual Studio membangun karena ketidaksesuaian, sehingga kompiler akan memancarkan peringatan ketika Anda melakukan ini.)

dan ekspresi berikut keduanya dievaluasi menjadi true:

std::is_class<Foo>::value
std::is_class<Bar>::value

Namun, harap perhatikan bahwa Anda tidak dapat mengganti kata kunci saat mendefinisikan ulang ; ini hanya karena (per aturan satu definisi) duplikat definisi kelas di seluruh unit terjemahan harus "terdiri dari urutan token yang sama" . Ini berarti Anda bahkan tidak dapat bertukar const int member;dengan int const member;, dan tidak ada hubungannya dengan semantik classatau struct.

Lightness Races di Orbit
sumber
16
Ini sangat informatif, dan jujur ​​jawaban favorit saya. Semua orang memperlakukan mereka sebagai entitas yang terpisah, ketika di bawah tenda, mereka sama. Saya bertanya-tanya apakah definisi struct di lingkungan Arduino dianggap sebagai kelas cpp, mengingat itu dikompilasi menggunakan g ++.
Benjamin
4
@ Ben Tentu saja. Kompiler Arduino mengkompilasi C ++; itulah akhirnya.
underscore_d
7
Jadi, jika saya memahami hak ini: Selama pengubah visibilitas Anda eksplisit, tidak dihilangkan, tidak masalah. Anda bisa menulis aplikasi C ++ yang sangat besar hanya menggunakan struct; atau Anda bisa melewati dan mengubah setiap kasus struct ke kelas. Selama Anda tidak menggunakan visibilitas default, aplikasi akan persis sama.
Ryan Lundy
Saya tidak yakin bahwa satu unit terjemahan dari program C ++ dapat memiliki deklarasi lengkap class foo { public: ... };dan yang lain dapat memiliki struct foo { ... };yang harus berlaku sesuai dengan klaim "benar-benar setara". Muncul alasan bahwa deklarasi tidak lengkap struct foo;dan class foo;dapat dipertukarkan. Ini tidak menentukan kelas tubuh, dan sehingga mereka tidak berbicara apa-apa dengan tata letak akses.
Kaz
@ Ka: Anda benar - jika definisi untuk tipe yang benar-benar sama, mereka harus identik secara leksikal agar perilaku didefinisikan dengan baik. The struct-key dan kelas-key sebaliknya logis ditukar meskipun (di mana semantik tidak terpengaruh), dan Foodan Barmasih setara / jenis identik. Saya memang memastikan untuk mengatakan "ketika redeclaring " dan memberikan contoh. Kalau dipikir-pikir, saya akan mengklarifikasi ini dalam jawaban untuk memastikan saya tidak menyesatkan orang ke UB
Lightness Races in Orbit
54

Satu-satunya waktu saya menggunakan struct bukan kelas adalah ketika mendeklarasikan functor tepat sebelum menggunakannya dalam pemanggilan fungsi dan ingin meminimalkan sintaksis demi kejelasan. misalnya:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 
Ferruccio
sumber
35
Sekarang beberapa tahun kemudian dan C ++ 11 didukung oleh semua kompiler utama, Lambdas membuat ini lebih ringkas .
36

Dari C ++ FAQ Lite :

Anggota dan kelas dasar dari suatu struct adalah publik secara default, sementara di kelas, mereka default ke pribadi. Catatan: Anda harus membuat kelas basis Anda secara eksplisit publik, pribadi, atau dilindungi, daripada mengandalkan default.

struct dan kelas dinyatakan setara secara fungsional.

OK, cukup bicara techno bersih yang melengking itu. Secara emosional, sebagian besar pengembang membuat perbedaan yang kuat antara kelas dan struct. Sebuah struct hanya terasa seperti tumpukan bit terbuka dengan sangat sedikit dalam cara enkapsulasi atau fungsionalitas. Kelas terasa seperti anggota masyarakat yang hidup dan bertanggung jawab dengan layanan cerdas, penghalang enkapsulasi yang kuat, dan antarmuka yang terdefinisi dengan baik. Karena itu konotasi yang sudah dimiliki kebanyakan orang, Anda mungkin harus menggunakan kata kunci struct jika Anda memiliki kelas yang memiliki sangat sedikit metode dan memiliki data publik (hal-hal seperti itu ada dalam sistem yang dirancang dengan baik!), Tetapi jika tidak, Anda mungkin harus menggunakan kelas tersebut kata kunci.

Tal Pressman
sumber
1
Saya tidak mengerti mengapa mereka menyatakan bahwa struct dan kelas secara fungsional sama, tetapi mengatakan lebih suka yang satu daripada yang lain dalam kasus-kasus tertentu tanpa alasan ..
deetz
3
Alasannya adalah konvensi. Kompiler tidak peduli yang mana yang Anda gunakan, tetapi pengembang lain yang melihat kode Anda akan lebih mudah memahami apa yang Anda maksudkan.
Tal Pressman
3
@deetz: Seluruh paragraf ketiga adalah alasan.
Lightness Races dalam Orbit
Wow, datang dari 'sekolah tua' saya tidak tahu bahwa struct bisa memiliki metode dan bahkan warisan. Saya selalu menggunakan struct ketika menggunakan hanya data saja tanpa metode dan biasanya ketika berurusan dengan kode API yang membutuhkan struct. Bisakah struct juga mendukung multiple inheritance?
Paul McCarthy
21

Satu tempat di mana struct telah membantu saya adalah ketika saya memiliki sistem yang menerima pesan format tetap (lebih dari katakan, port serial) dari sistem lain. Anda bisa memasukkan aliran byte ke dalam struktur yang mendefinisikan bidang Anda, dan kemudian dengan mudah mengakses bidang.

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

Jelas, ini adalah hal yang sama yang akan Anda lakukan di C, tetapi saya menemukan bahwa overhead harus men-decode pesan ke dalam kelas biasanya tidak sepadan.

mbyrne215
sumber
Hal yang sama dapat dicapai dalam C.
Eugene Bujak
11
Atau Anda bisa menerapkan operator >>pada kelas alih-alih menulis processMessagefungsi, yang akan membuat C ++ Anda lebih mirip C ++ yang tepat dan kurang seperti C.
Nick Bastin
1
Selain fakta bahwa itu tidak portabel antara sistem yang berbeda, ini melanggar aturan alias, jadi tidak dijamin untuk bekerja bahkan dalam arsitektur tunggal.
underscore_d
@underscore_d Ini dapat bekerja platform (tapi bukan kompiler) independen, tetapi Anda harus menggunakan bitfields tetap, sebuah __packed__struct dan memiliki implementasi ifdef endian-aware (Anda perlu membalik urutan pada mesin di mana endianess berlawanan dengan apa yang sumber data eksternal menyediakan). Ini tidak cantik, tapi saya sudah terbiasa mengemas / membongkar register untuk periferal jarak jauh pada platform tertanam dengan cara yang portabel.
crasic
1
@ Jacwah Huh, poin bagus. Aliasing tidak akan menjadi masalah di sini karena salah satu petunjuknya adalah chartipe, yang dikecualikan dari alias. Namun, masih ada masalah, meskipun yang berbeda: Casting char*ke tipe yang berbeda, jika tidak benar-benar ada objek dari tipe terakhir yang sudah diinisialisasi di alamat itu, adalah UB karena melanggar aturan seumur hidup. Afaik, bahkan jika jenis tujuan sepele dibangun, hanya memiliki memori yang dialokasikan tidak cukup untuk C ++ untuk secara resmi memungkinkan memperlakukan memori itu sebagai jenis itu.
underscore_d
19

Anda dapat menggunakan "struct" di C ++ jika Anda menulis pustaka yang internalnya adalah C ++ tetapi API dapat dipanggil dengan kode C atau C ++. Anda cukup membuat satu tajuk yang berisi fungsi struct dan API global yang Anda paparkan ke kode C dan C ++ karena ini:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

Kemudian Anda dapat menulis bilah fungsi () dalam file C ++ menggunakan kode C ++ dan membuatnya bisa dipanggil dari C dan kedua dunia dapat berbagi data melalui struct yang dinyatakan. Ada peringatan lain tentu saja ketika mencampur C dan C ++ tetapi ini adalah contoh yang disederhanakan.

Adisak
sumber
2
Jawaban pas terbaik. Kompatibilitas-C adalah alasan terpenting. semua hal lain seperti akses default adalah esoterik.
Valentin Heinitz
16

Seperti yang dikatakan setiap orang, satu-satunya perbedaan nyata adalah akses default. Tapi saya terutama menggunakan struct ketika saya tidak ingin segala macam enkapsulasi dengan kelas data sederhana, bahkan jika saya menerapkan beberapa metode pembantu. Misalnya, ketika saya membutuhkan sesuatu seperti ini:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};
ogoid
sumber
1
+1 untuk memberi contoh struct dengan beberapa fungsi anggota yang tidak terasa seperti Anda telah "mengambil strukturnya".
einpoklum
9

Untuk menjawab pertanyaan saya sendiri (tanpa malu-malu), Seperti telah disebutkan, hak akses adalah satu-satunya perbedaan di antara mereka di C ++.

Saya cenderung menggunakan struct untuk penyimpanan data saja. Saya akan mengizinkannya untuk mendapatkan beberapa fungsi pembantu jika membuatnya bekerja dengan data lebih mudah. Namun begitu data membutuhkan kontrol aliran (yaitu getter / setter yang mempertahankan atau melindungi keadaan internal) atau mulai mengakuisisi setiap fungsi utama (pada dasarnya lebih seperti objek), itu akan 'ditingkatkan' ke kelas untuk mengomunikasikan maksud yang lebih baik.

Alan Hinchcliffe
sumber
9

Structs ( PODs , lebih umum) berguna ketika Anda menyediakan antarmuka yang kompatibel dengan C dengan implementasi C ++, karena mereka portabel melintasi batas-batas bahasa dan format tautan.

Jika itu bukan masalah bagi Anda, maka saya kira penggunaan "struct" bukan "kelas" adalah komunikator yang baik (seperti @ZeroSignal katakan di atas). Structs juga memiliki semantik penyalinan yang lebih mudah diprediksi, sehingga mereka berguna untuk data yang ingin Anda tulis ke media eksternal atau kirim melalui kabel.

Structs juga berguna untuk berbagai tugas pemrograman metaprogram, seperti templat ciri yang baru saja memaparkan sekelompok typedef dependen:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

... Tapi itu benar-benar hanya mengambil keuntungan dari tingkat perlindungan default struct menjadi publik ...

argv0
sumber
1
Itu bukan penggunaan POD yang benar. Sebuah struct (atau kelas) dapat menjadi POD struct jika (dan hanya jika) mengandung HANYA anggota POD.
Martin York
4
"semantik penyalinan yang dapat diprediksi": Symantics sama dengan untuk kelas (dan memiliki masalah yang sama (salinan dangkal)).
Martin York
2
Posting ini akan membuat Anda percaya (semoga tidak sengaja) bahwa semua struct adalah POD. Ini sama sekali tidak benar. Saya harap orang-orang tidak disesatkan oleh ini.
Michael Dorst
8

Untuk C ++, sebenarnya tidak ada banyak perbedaan antara struct dan kelas. Perbedaan fungsional utama adalah bahwa anggota struct adalah publik secara default, sementara mereka pribadi secara default di kelas. Kalau tidak, sejauh bahasanya, mereka setara.

Yang mengatakan, saya cenderung menggunakan struct di C ++ seperti yang saya lakukan di C #, mirip dengan apa yang dikatakan Brian. Struct adalah wadah data sederhana, sementara kelas digunakan untuk objek yang perlu bertindak pada data selain hanya berpegang pada itu.

Andy
sumber
4

Mereka adalah hal yang hampir sama. Berkat keajaiban C ++, sebuah struct dapat menyimpan fungsi, menggunakan pewarisan, dibuat menggunakan "baru" dan seterusnya seperti kelas

Satu-satunya perbedaan fungsional adalah bahwa kelas dimulai dengan hak akses pribadi, sedangkan struct dimulai dengan publik. Ini adalah menjaga kompatibilitas mundur dengan C.

Dalam praktiknya, saya selalu menggunakan struct sebagai pemegang data dan kelas sebagai objek.

penuh teka-teki
sumber
4

Seperti yang ditunjukkan orang lain

  • keduanya setara terlepas dari visibilitas default
  • mungkin ada alasan untuk dipaksa menggunakan yang satu atau yang lain dengan alasan apa pun

Ada rekomendasi yang jelas tentang kapan harus menggunakan yang dari Stroustrup / Sutter:

Gunakan kelas jika kelas memiliki invarian; gunakan struct jika anggota data dapat bervariasi secara independen

Namun, perlu diingat bahwa tidak bijaksana untuk maju menyatakan sth. sebagai kelas ( class X;) dan mendefinisikannya sebagai struct ( struct X { ... }). Ini dapat bekerja pada beberapa penghubung (misalnya, g ++) dan mungkin gagal pada yang lain (misalnya, MSVC), sehingga Anda akan menemukan diri Anda dalam neraka pengembang.

pasbi
sumber
Bisakah Anda menjelaskan masalah tautan ini?
Lightness Races di Orbit
@LightnessRacesinOrbit Aku tidak bisa, sayangnya. Saya bahkan tidak bisa membuat contoh. Sepele class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }tidak hanya mengkompilasi dan berjalan dengan MSVC 2017, bahkan menghasilkan peringatan yang jelas yang Foodinyatakan sebagai structtetapi didefinisikan sebagai class. Tetapi saya juga ingat dengan jelas bahwa tim kami menghabiskan setengah hari untuk menemukan bug bodoh itu. Saya tidak yakin versi MSVC apa yang kami gunakan saat itu.
pasbi
Linker bahkan tidak boleh tahu tentang apakah Anda menggunakan classatau structpada deklarasi maju, dan keduanya secara bebas dipertukarkan sesuai standar (meskipun diketahui bahwa VS memperingatkan; Saya selalu berasumsi bahwa itu hanya untuk menghindari kesalahan programmer yang jelas). Sesuatu tidak berbau di sini. Apakah Anda yakin itu bukan bug pelanggaran ODR?
Lightness Races dalam Orbit
1
Hmm, sepertinya VS tidak patuh dalam hal ini (gambar)
Lightness Races in Orbit
Saya tidak ingat persisnya. Masalahnya tidak terjadi dalam aplikasi secara langsung, tetapi di perpustakaan yang digunakan dalam gtest. Saya hanya tahu bahwa penghubung menghasilkan kesalahan yang tidak dapat dipahami (LNK ???). Setelah saya mengganti struct-forwards ke class-forwards, masalahnya hilang. Sampai hari ini, saya merasa aneh juga. Saya akan senang jika Anda bisa menjelaskannya.
pasbi
3

Kelas.

Anggota kelas bersifat pribadi secara default.

class test_one {
    int main_one();
};

Setara dengan

class test_one {
  private:
    int main_one();
};

Jadi, jika Anda mencoba

int two = one.main_one();

Kami akan mendapatkan kesalahan: main_one is privatekarena tidak dapat diakses. Kita dapat menyelesaikannya dengan menginisialisasi dengan menentukan publik yaitu

class test_one {
  public:
    int main_one();
};

Struct.

Sebuah struct adalah kelas di mana anggota bersifat publik secara default.

struct test_one {
    int main_one;
};

Artinya main_oneadalah pribadi

class test_one {
  public:
    int main_one;
};

Saya menggunakan struct untuk struktur data di mana anggota dapat mengambil nilai apa pun, lebih mudah seperti itu.

Farhan
sumber
3

Keuntungan structlebih classadalah menyimpan satu baris kode, jika mengikuti "anggota publik pertama, lalu pribadi". Dalam terang ini, saya menemukan kata kunci classtidak berguna.

Berikut adalah alasan lain untuk menggunakan saja structdan tidak pernah class. Beberapa pedoman gaya kode untuk C ++ menyarankan menggunakan huruf kecil untuk makro fungsi, alasannya adalah bahwa ketika makro dikonversi ke fungsi inline, namanya tidak perlu diubah. Sama disini. Anda memiliki struct C-style yang bagus dan suatu hari, Anda tahu Anda perlu menambahkan konstruktor, atau beberapa metode kenyamanan. Apakah Anda mengubahnya menjadi class? Dimana mana?

Membedakan antara structs dan classes adalah terlalu banyak kesulitan, masuk ke cara melakukan apa yang seharusnya kita lakukan - pemrograman. Seperti banyak masalah C ++, masalah ini muncul karena keinginan kuat untuk kompatibilitas.

Vorac
sumber
Mengapa Anda perlu mengubahnya menjadi class? Apakah Anda berpikir bahwa kelas yang ditentukan dengan structkata kunci tidak dapat memiliki fungsi anggota atau konstruktor?
Lightness Races dalam Orbit
@LightnessRacesinOrbit karena 1. konsistensi dan 2. beberapa analis statis mengeluh tentang pelanggaran 1.
Vorac
Itu tidak mengikuti. "Konsistensi" apa lagi yang Anda patuhi? Setiap kelas dengan anggota yang dipanggil joe()harus ditentukan dengan classkata kunci? Setiap kelas dengan minimal 4 intanggota harus didefinisikan dengan structkata kunci?
Lightness Races dalam Orbit
@LightnessRacesinOrbit Saya mengacu pada ungkapan "agregat POD didefinisikan dengan struct, agregat dengan metode didefinisikan dengan class". Terlalu banyak kerumitan.
Vorac
2

mereka adalah hal yang sama dengan standar yang berbeda (pribadi secara default untuk class, dan publik secara default untuk struct), jadi secara teori mereka benar-benar dapat dipertukarkan.

jadi, jika saya hanya ingin mengemas beberapa info untuk bergerak, saya menggunakan struct, bahkan jika saya meletakkan beberapa metode di sana (tetapi tidak banyak). Jika sebagian besar hal-hal yang buram, di mana penggunaan utama akan melalui metode, dan tidak langsung ke anggota data, saya menggunakan kelas penuh.

Javier
sumber
2

Structs secara default memiliki akses publik dan kelas-kelas secara default memiliki akses pribadi.

Secara pribadi saya menggunakan struct untuk Objek Transfer Data atau sebagai Objek Nilai. Ketika digunakan seperti itu saya menyatakan semua anggota sebagai const untuk mencegah modifikasi oleh kode lain.

anio
sumber
2

Keduanya structdan classsama di bawah tenda meskipun dengan standar berbeda untuk visibilitas, structdefault adalah publik dan classdefault adalah pribadi. Anda dapat mengubah salah satu menjadi yang lain dengan penggunaan privatedanpublic . Keduanya memungkinkan pewarisan, metode, konstruktor, destruktor, dan semua barang lainnya dari bahasa yang berorientasi objek.

Namun satu perbedaan besar antara keduanya adalah bahwa structsebagai kata kunci didukung dalam C sedangkan classtidak. Ini berarti bahwa seseorang dapat menggunakan structdalam include file yang dapat #includemenjadi baik C ++ atau C asalkan structadalah C gaya polos structdan segala sesuatu yang lain di include file kompatibel dengan C, yaitu tidak ada C ++ kata kunci tertentu seperti private, public, tidak ada metode, tidak ada warisan, dll. dll.

Gaya AC structdapat digunakan dengan antarmuka lain yang mendukung penggunaan gaya C structuntuk membawa data bolak-balik melalui antarmuka.

Gaya AC structadalah sejenis templat (bukan templat C ++ tetapi lebih merupakan pola atau stensil) yang menggambarkan tata letak area memori. Selama bertahun-tahun interface yang dapat digunakan dari C dan dengan C plug-in (inilah melihat Anda Java dan Python dan Visual Basic) telah menciptakan beberapa yang bekerja dengan gaya C struct.

Richard Chambers
sumber
1

Secara teknis keduanya sama dalam C ++ - misalnya mungkin untuk struct memiliki operator kelebihan beban dll.

Namun:

Saya menggunakan struct ketika saya ingin menyampaikan informasi dari beberapa jenis secara bersamaan saya menggunakan kelas ketika saya berurusan dengan objek "fungsional".

Semoga ini bisa membantu.

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

Misalnya, saya mengembalikan siswa struct di metode get ... () di sini - selamat menikmati.

Maciek
sumber
1

Kapan Anda memilih untuk menggunakan struct dan kapan harus menggunakan kelas di C ++?

Saya gunakan structketika saya mendefinisikan functorsdan POD. Kalau tidak saya gunakan class.

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};
AraK
sumber
1
Jawaban ini menunjukkan tanda-tanda usia :) std::binary_function<>tidak hanya usang, c ++ 17 bahkan menghapusnya.
lihat
Tidak mengherankan karena ditulis pada zaman C ++ 03, bahasa yang didefinisikan 15 tahun lalu.
Lightness Races dalam Orbit
1

Saya menggunakan struct ketika saya perlu membuat tipe POD atau functor.

ivan.ukr
sumber
1

Semua anggota kelas adalah pribadi secara default dan semua anggota struct adalah publik secara default. Kelas memiliki pangkalan pribadi default dan Struct memiliki pangkalan publik default. Struct dalam kasus C tidak dapat memiliki fungsi anggota di mana seperti dalam kasus C ++ kita dapat memiliki fungsi anggota yang ditambahkan ke struct. Selain perbedaan-perbedaan ini, saya tidak menemukan sesuatu yang mengejutkan tentang mereka.

Membantu Kacang
sumber
0

Saya menggunakan struct hanya ketika saya perlu menyimpan beberapa data tanpa fungsi anggota yang terkait dengannya (untuk beroperasi pada data anggota) dan untuk mengakses variabel data secara langsung.

Misalnya: Membaca / Menulis data dari file dan aliran socket dll. Melewati argumen fungsi dalam struktur di mana argumen fungsi terlalu banyak dan sintaks fungsi terlihat terlalu panjang.

Secara teknis tidak ada perbedaan besar antara kelas dan struture kecuali aksesibilitas default. Terlebih lagi itu tergantung pada gaya pemrograman bagaimana Anda menggunakannya.

harik
sumber
-4

Saya berpikir bahwa Structs dimaksudkan sebagai Struktur Data (seperti array tipe data multi-data) dan kelas diintegrasikan untuk Pengemasan Kode (seperti koleksi subrutin & fungsi).

:(

GaiusSensei
sumber
-6

Saya tidak pernah menggunakan "struct" di C ++.

Saya tidak pernah bisa membayangkan skenario di mana Anda akan menggunakan struct ketika Anda ingin anggota pribadi, kecuali Anda sengaja berusaha untuk membingungkan.

Tampaknya menggunakan struct lebih merupakan indikasi sintaksis tentang bagaimana data akan digunakan, tetapi saya lebih suka hanya membuat kelas dan mencoba membuatnya secara eksplisit atas nama kelas, atau melalui komentar.

Misalnya

class PublicInputData {
    //data members
 };
Baltimark
sumber
Menurut saya, "indikasi sintaksis tentang bagaimana data akan digunakan" adalah alasan yang sangat baik untuk menggunakan struct, terutama jika alternatifnya adalah menggunakan komentar atau nama dalam nama kelas.
Viktor Sehr
2
Bukankah mendeklarasikan structsudah cukup eksplisit bahwa anggota kelas akan, secara default, publik?
nama pengguna salah