Struktur C / C ++ vs Kelas

108

Setelah menyelesaikan kelas C ++ saya, menurut saya struct / class hampir identik kecuali dengan beberapa perbedaan kecil.

Saya tidak pernah memprogram dalam C sebelumnya; tapi saya tahu itu memiliki struct. Dalam C apakah mungkin untuk mewarisi struct lain dan mengatur pengubah publik / pribadi?

Jika Anda dapat melakukan ini dalam C biasa, mengapa kita membutuhkan C ++? Apa yang membuat kelas berbeda dari struct?


sumber
kemungkinan duplikat stackoverflow.com/questions/54585/…
gonzobrains

Jawaban:

146

Di C ++ , struct dan class hampir sama; satu-satunya perbedaan adalah di mana pengubah akses (untuk variabel anggota, metode, dan kelas dasar) di kelas secara default ke privat, pengubah akses di struct default ke publik.

Namun, di C , struct hanyalah kumpulan agregat dari data (publik), dan tidak memiliki fitur seperti kelas lainnya: tidak ada metode, tidak ada konstruktor, tidak ada kelas dasar, dll. Meskipun C ++ mewarisi kata kunci, ia memperluas semantik. (Ini, bagaimanapun, adalah mengapa hal-hal default ke publik dalam struct — sebuah struct yang ditulis seperti struct C berperilaku seperti itu.)

Meskipun memungkinkan untuk memalsukan beberapa OOP di C — misalnya, mendefinisikan fungsi yang semuanya membawa pointer ke struct sebagai parameter pertamanya, atau terkadang memaksa struct dengan beberapa bidang pertama yang sama menjadi "sub / superclass" —itu selalu semacam dinyalakan, dan sebenarnya bukan bagian dari bahasa.

Antal Spector-Zabusky
sumber
Dari calon .Net, OOP orang telah mendefinisikannya dengan cara ini. ✓ PERTIMBANGKAN mendefinisikan sebuah struct alih-alih kelas jika contoh tipe kecil dan umumnya berumur pendek atau biasanya tertanam di objek lain. X HINDARI mendefinisikan struct kecuali tipe memiliki semua karakteristik berikut: 1. Secara logis mewakili satu nilai, mirip dengan tipe primitif (int, double, dll.). 2. Ini memiliki ukuran instance di bawah 16 byte. 3. Itu tidak bisa diubah.
Abhijeet
5
@Abhijeet Itulah perbedaan antara struct dan class di C #, tapi itu tidak relevan dengan C ++, dan bahkan lebih untuk C. Dalam C #, class dan struct sebenarnya berbeda; tidak demikian halnya di C ++, dan C hanya memiliki struct tanpa OO.
Antal Spector-Zabusky
tidak akan lebih baik untuk menyimpan semantik C yang sama di struct C ++? dan bila diminta untuk menggunakan "struct dengan cara c ++" cukup gunakan kelas? Saya tidak pernah mendapatkan keuntungan dari memiliki struct "augmented" di C ++ dibandingkan dengan C. Saya suka masih menggunakan struct seperti yang dirancang di C, jika tidak gunakan kelas, dengan beberapa pengecualian diperbolehkan.
Raffaello
15

Selain itu perbedaan akses default (publik / privat), tidak ada perbedaan.

Namun, beberapa toko yang membuat kode dalam C dan C ++ akan menggunakan "class / struct" untuk menunjukkan apa yang dapat digunakan dalam C dan C ++ (struct) dan yang hanya C ++ (kelas). Dengan kata lain, dalam gaya ini semua struct harus bekerja dengan C dan C ++. Inilah mengapa ada perbedaan di tempat pertama dahulu kala, saat C ++ masih dikenal sebagai "C dengan Kelas."

Perhatikan bahwa serikat C bekerja dengan C ++, tetapi tidak sebaliknya. Sebagai contoh

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

Dan juga

typedef union friend{
    int a;
    float b;
} class;

hanya bekerja di C

Lance Diduck
sumber
9
Menggunakan kata kunci cpp dalam kode c Anda dan kemudian mengklaim itu tidak kompatibel dengan cpp agak bodoh
Dani
7

Saya akan menambahkan jawaban yang ada karena C ++ modern sekarang menjadi sesuatu dan Panduan Inti resmi telah dibuat untuk membantu dengan pertanyaan seperti ini.

Berikut bagian yang relevan dari pedoman:

C.2: Gunakan kelas jika kelas memiliki invarian; gunakan struct jika anggota data dapat berbeda secara independen

Invarian adalah kondisi logis untuk anggota objek yang harus dibuat oleh konstruktor agar fungsi anggota publik dapat digunakan. Setelah invarian dibuat (biasanya oleh konstruktor) setiap fungsi anggota dapat dipanggil untuk objek tersebut. Suatu invarian dapat dinyatakan secara informal (misalnya, dalam komentar) atau secara lebih formal menggunakan Expects.

Jika semua anggota data dapat berbeda secara independen satu sama lain, tidak ada invarian yang memungkinkan.

Jika kelas memiliki data pribadi, pengguna tidak dapat sepenuhnya menginisialisasi objek tanpa menggunakan konstruktor. Oleh karena itu, definisi kelas akan menyediakan konstruktor dan harus menentukan artinya. Ini secara efektif berarti kebutuhan definer untuk mendefinisikan suatu invarian.

Pelaksanaan

Cari struct dengan semua data pribadi dan kelas dengan anggota publik.

Contoh kode yang diberikan:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

ClassIni bekerja dengan baik untuk anggota yang, misalnya, berasal dari satu sama lain atau saling terkait. Mereka juga dapat membantu dengan pemeriksaan kewarasan pada instansiasi. Structs bekerja dengan baik untuk memiliki "kantong data", di mana tidak ada hal istimewa yang benar-benar terjadi tetapi para anggota secara logis masuk akal untuk dikelompokkan bersama.

Dari sini, masuk akal bahwa classada untuk mendukung enkapsulasi dan konsep pengkodean terkait lainnya, yang structtidak terlalu berguna untuk itu.

Dave
sumber
Satu pertimbangan lainnya adalah portabilitas. structs adalah yang paling portabel. Mereka dapat digunakan oleh C atau C ++ atau bolak-balik. Mereka juga dapat dibuka dengan Python menggunakan structmodul, misalnya. Jika proyek Anda memprioritaskan kompatibilitas dengan bahasa, antarmuka, atau sistem lain, lebih suka structdaripada class. Untuk urusan internal program, lebih suka class.
Dave
6

Tidak mungkin untuk mendefinisikan fungsi anggota atau mendapatkan struct dari satu sama lain di C.

Juga, C ++ tidak hanya C + "derive struct". Template, referensi, ruang nama yang ditentukan pengguna, dan operator yang membebani semuanya tidak ada di C.

Johannes Schaub - litb
sumber
Saya tahu bahwa template, dll tidak ada di C tapi saya tidak mengetahui powerdari struct di C. Jadi C ++ hanya menggunakan struct agar 'mundur' kompatibel dengan C?
4
Hanya untuk kompatibilitas mundur? Secara praktis mungkin ada sesuatu untuk itu, tetapi perbedaannya bisa menjadi sinyal niat: di mana saya menggunakan yang structsaya maksud adalah jenis barang yang sebagian besar pasif POD.
dmckee --- kucing bekas moderator
@ dmckee: Untuk apa nilainya, kebanyakan Fungsional STL (yaitu std::less) didefinisikan sebagai struct, bukan kelas.
Billy ONeal
1
C ++ tidak sepenuhnya mendukung backards dengan C. Anda bisa mengatakan bahwa kata kunci struct adalah akomodasi untuk pengembang C. Saya suka kata kunci struct untuk kelas yang hanya menyimpan data secara teratur tetapi tidak memberikan (banyak) logika itu sendiri.
ypnos
@ypnos: Lihat komentar terakhir saya. Satu-satunya perbedaan antara keduanya adalah bahwa salah satu anggotanya adalah default publik, dan yang lainnya default privat.
Billy ONeal
3

Satu lagi perbedaan dalam C ++, ketika Anda mewarisi kelas dari struct tanpa penentu akses, itu menjadi warisan publik sedangkan dalam kasus kelas itu warisan pribadi.

MarsRover
sumber
1

C ++ menggunakan struct terutama untuk 1) kompatibilitas mundur dengan C dan 2) jenis POD. C struct tidak memiliki metode, pewarisan atau visibilitas.

Chris Hafey
sumber
2
Untuk apa nilainya, kebanyakan fungsi STL (yaitu std::less) didefinisikan sebagai struct, bukan kelas.
Billy ONeal
3
Perhatikan bahwa struct C ++ memang memiliki metode, pewarisan, dan visibilitas.
robertwb
c struct dapat menyertakan penunjuk fungsi meskipun sebagai tipe (* addr) (params);
Kesalahan