Saya baru-baru ini terjebak dalam situasi seperti ini:
class A
{
public:
typedef struct/class {...} B;
...
C::D *someField;
}
class C
{
public:
typedef struct/class {...} D;
...
A::B *someField;
}
Biasanya Anda dapat mendeklarasikan nama kelas:
class A;
Tapi Anda tidak bisa meneruskan menyatakan tipe bersarang, berikut ini menyebabkan kesalahan kompilasi.
class C::D;
Ada ide?
c++
class
nested
forward-declaration
Calmarius
sumber
sumber
Jawaban:
Anda tidak dapat melakukannya, itu adalah lubang dalam bahasa C ++. Anda harus melepaskan sarang setidaknya dari salah satu kelas bersarang.
sumber
Saya membutuhkan referensi ke depan seperti:
Solusi saya adalah:
Kemudian ketika saya bisa menggunakan definisi lengkap:
Teknik ini mungkin akan lebih merepotkan daripada nilainya jika ada konstruktor yang rumit atau fungsi anggota khusus lainnya yang tidak diwarisi dengan lancar. Saya bisa membayangkan sihir template tertentu bereaksi buruk.
Tetapi dalam kasus saya yang sangat sederhana, tampaknya berhasil.
sumber
using basename::basename;
di dalam kelas turunan, sehingga tidak ada masalah dengan ctors yang rumit.typedef
di dalam kelasJika Anda benar-benar ingin menghindari #termasuk file header jahat di file header Anda, Anda bisa melakukan ini:
file hpp:
file cpp
Tapi kemudian:
Jadi, yeah, pengorbanan ...
sumber
hpp
file?Ini dapat dilakukan dengan meneruskan mendeklarasikan kelas luar sebagai namespace .
Contoh: Kita harus menggunakan kelas bersarang lain :: A :: Bersarang di others_a.h, yang di luar kendali kami.
others_a.h
my_class.h
my_class.cpp
sumber
a::b
hancur dengan cara yang sama, tidak peduli apakaha
kelas atau namespace.Saya tidak akan menyebut ini sebagai jawaban, tetapi tetap saja merupakan temuan yang menarik: Jika Anda mengulangi deklarasi struct Anda dalam namespace yang disebut C, semuanya baik-baik saja (setidaknya dalam gcc). Ketika definisi kelas dari C ditemukan, tampaknya secara diam-diam menimpa namspace C.
sumber
Ini akan menjadi solusi (setidaknya untuk masalah yang dijelaskan dalam pertanyaan - bukan untuk masalah aktual, yaitu, ketika tidak memiliki kendali atas definisi
C
):sumber
Jika Anda memiliki akses untuk mengubah kode sumber kelas C dan D, maka Anda dapat mengambil kelas D secara terpisah, dan memasukkan sinonim untuknya di kelas C:
sumber