melemparkan objek kelas ke objek struct C / C ++

Nov 27 2020

Saya memiliki dua proyek satu di C dan yang lainnya di C ++ dan saya mencoba mentransmisikan objek kelas dalam C ++ ke objek struktur di C. Misalnya, saya memiliki objek dari myClass yang saya coba masukkan ke myStru sebagai berikut:

Dalam proyek C ++ saya, saya memiliki kelas ini:

class myClass{
    myClass();
    ~myClass();
    char    *data;
    int     var;
}

Dalam proyek C saya, saya memiliki struktur ini:

struct myStru {
    char  *data;
    int    var;
};
typedef struct myStru myStru;

Sekarang di proyek C ++ saya, saya membuat objek dari myClass:

myClass *classObj = new myClass();
classObj->data = new char[10];
classObj->var  = 99;

Dalam proyek C saya, saya menerima classObjsebagai penunjuk kosong dan saya mencoba memasukkannya sebagai berikut:

myStru *struObj = (myStru*)malloc(sizeof(struct myStru));
struObj = (myStru*) classObj;
printf(" struObj->var %d \n", struObj->var); // this print 99

Saya melakukan ini nanti di proyek C ++ saya

   delete []classObj->data; // I know smart pointers can be used here but this is not my point in this question now
    delete  classObj;

Apakah yang saya lakukan di sini benar? yaitu, mentransmisikan classObjke struObjdengan cara itu?

Contoh lengkapnya dapat ditemukan di sini (terima kasih @Borgleader) http://coliru.stacked-crooked.com/a/05543b944ee23f2f

EDIT: Saya menemukan jawaban yang bagus untuk pertanyaan saya di artikel ini (lihat Mengakses Kelas C ++ dari C): https://www.oracle.com/technical-resources/articles/it-infrastructure/mixing-c-and-cplusplus.html

Jawaban

3 BartekBanachewicz Nov 27 2020 at 13:22

Saya tidak 100% yakin, karena ini C ++ dan Anda tidak akan pernah bisa, tapi menurut saya ini adalah perilaku yang tidak ditentukan.

Anda tidak dapat mengakses anggota struct melalui penunjuk ke anggota struct lain. Pengecualian penting dari aturan itu melibatkan pengaksesan urutan awal umum dari dua struct yang menjadi anggota serikat.

Ini bisa berfungsi jika Anda benar-benar mewarisi kelas Anda dari struct.

Atau, pengecualian lainnya adalah Anda dapat dengan aman berada di memcpyantara struct seperti itu, AFAIR.

1 Persixty Nov 27 2020 at 17:08

Pertanyaan ini tentang interoperabilitas dan Anda tidak akan pernah mendapatkan jawaban pasti karena bergantung pada aspek implementasi yang ditentukan dari compiler C dan C ++. The structdan classadalah tipe yang kompatibel dengan tata letak dalam istilah C ++. Sangat jelas bahwa mendeklarasikan satu a classdan satu a structbukanlah masalah dan karena keduanya memiliki akses-anggota yang sama untuk semua anggotanya (meskipun berbeda satu sama lain) yang kompatibel (setidaknya dalam C ++ 14 dan seterusnya saya percaya) .

Standar terbaik yang akan ditawarkan adalah:

Catatan: Kelas tata letak standar berguna untuk berkomunikasi dengan kode yang ditulis dalam bahasa pemrograman lain. Tata letaknya ditentukan dalam 12.2. - catatan akhir

The niat adalah bahwa kelas tersebut (yang keduanya standar-layout dan tata letak yang kompatibel) menjadi antar-beroperasi. Jika Anda menggunakan kompiler yang sama dalam dua mode maka akan 'mengecewakan' jika ini tidak berhasil. Tapi itu yang terbaik yang akan Anda 'mengecewakan' - periksa dokumentasinya.

Saya sedikit bertanya-tanya tentang manajemen sumber daya dalam keseluruhan strategi. Anda telah mendeklarasikan destruktor di C ++ classdan tidak apa-apa bukan virtual!), Tetapi Anda menyalinnya ke a structdi sisi C, jika kode C memiliki fungsi 'destruktor like' untuk menghancurkan objeknya yang dapat menyebabkan masalah karena Anda bitwise telah mengkloning objek C ++ (mudah-mudahan!).

Jika C memanggil free(s->data)salinan objek yang dibangun di C ++ yang telah digunakan, newAnda memprovokasi Undefined Behavior. Itu mungkin kasus pengecualian yang memerlukan penggunaan malloc()di sisi C ++ untuk kompatibilitas.

JADI itu mungkin OK, tetapi Anda mengandalkan kemampuan interoperabilitas antara C dan C ++ dan kedua standar membawa Anda sejauh mungkin tetapi menurut definisi Anda menggunakan fitur implementasi yang ditentukan.

Dengan catatan itu kita tahu standar itu bersedia untuk bekerja dan mungkin akan berhasil. Semoga berhasil!