Pertanyaan Perbedaan tata letak memori dalam struct


Saya memiliki struktur berikut di C ++

struct A {
  int a;
  double b;
  float c;
}

Apakah ada perbedaan dalam tata letak memori antara struct ini dan satu dengan fungsi yang ditambahkan ke dalamnya,

struct B {
  int a;
  double b;
  float c;
  void foo();
}
B::foo() { //do stuff }

5
2018-03-21 13:12


asal


Jawaban:


Standar C ++ menjamin bahwa susunan memori dari struct C dan kelas C ++ (atau struct - same thing) akan identik, asalkan kelas C ++ / struct sesuai dengan kriteria menjadi POD ("Plain Old Data"). Jadi apa arti POD?

Kelas atau struct adalah POD jika:

Semua anggota data adalah publik dan mereka sendiri POD atau tipe fundamental (tetapi bukan tipe referensi atau pointer-ke-anggota), atau array seperti

  • Ini tidak memiliki konstruktor yang ditentukan pengguna, operator penugasan atau destruktor
  • Tidak memiliki fungsi virtual
  • Ia tidak memiliki kelas dasar

Jadi ya dalam kasus Anda, tata letak memori adalah sama.

Sumber: Struktur Objek C ++ dalam Memori Vs sebuah Struct


8
2018-03-21 13:20



Sejak A dan B adalah tata letak standar1, dan urutan awal umum mereka terdiri dari setiap anggota data non-statis2, mereka Layout-layout.

Apakah ada perbedaan dalam tata letak memori antara struct ini dan satu dengan fungsi yang ditambahkan ke dalamnya

Standar hanya menggambarkan semantik dari mesin abstrak, jadi tidak ada menjamin sebuah objek tipe A akan diwakili dalam memori sebagai objek tipe B, tapi Layout-layout tipe cenderung.


1)  [class]/7

Kelas tata letak standar adalah kelas yang:

  • tidak memiliki anggota data non-statis dari tipe kelas tata-letak non-standar (atau larik jenis tersebut) atau referensi,
  • tidak memiliki fungsi virtual (10.3) dan tidak ada kelas dasar virtual (10.1),
  • memiliki kontrol akses yang sama (Ayat 11) untuk semua anggota data non-statis,
  • tidak memiliki kelas dasar non-tata letak standar,   tidak memiliki anggota data non-statis di kelas paling turunan dan paling banyak satu kelas dasar dengan anggota data non-statis, atau tidak memiliki kelas dasar dengan anggota data non-statis, dan
  • tidak memiliki kelas dasar dengan tipe yang sama dengan anggota data non-statis pertama.

2)  [class.mem]/21 & [class.mem]/22 

Dua tipe struct tata letak standar (Klausa 9) adalah tipe yang kompatibel dengan tata letak jika mereka memiliki jumlah anggota data non-statis yang sama dan anggota data non-statik yang bersesuaian (dalam urutan deklarasi) memiliki tipe tata letak yang kompatibel (3.9).


4
2018-03-21 13:24



Secara formal tergantung pada kompilator Anda, tetapi kompilator di mana menyatakan fungsi anggota non-virtual mengubah tata letak kelas akan menjadi sabotase batas. Anda memerlukan stabilitas semacam ini untuk menegakkan kompatibilitas di mana objek bersama bergantung pada setiap platform.


2
2018-03-21 13:16



Iya dan tidak...

Dalam kasus spesifik Anda, tidak. Struct tidak lebih dari sebuah wadah data, dan fungsi berada di tempat lain. Ketika fungsi dipanggil, pointer ke struct dilewatkan sebagai parameter tambahan, implisit pertama yang muncul sebagai this penunjuk dalam fungsi.

Masalah berubah, meskipun, jika Anda menambahkan virtualfungsi. Meskipun standar C ++ tidak mengamanatkannya, vtables adalah defacto standar, dan kelas akan menerima pointer ke vtable sebagai anggota pertama, tetapi tidak terlihat. Anda dapat mencobanya dengan mencetak ukuran objek sebelum dan setelah menambahkan fungsi virtual.

Di sisi lain, jika kelas aku s virtual sudah karena mewarisi dari kelas lain yang sudah memiliki fungsi virtual, tata letak memori tidak akan berubah lagi karena sudah ada pointer ke vtable termasuk (meskipun akan menunjuk ke lokasi yang berbeda untuk instance dari sub-kelas) .


1
2018-03-21 13:23