Bagaimana untuk Menyelesaikan Kekaburan dalam Berbilang Warisan dengan Jenis Bertindih Apabila Memanggil Kaedah Polimorfik?

Linda Hamilton
Lepaskan: 2024-10-25 06:23:02
asal
253 orang telah melayarinya

How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?

Nyahkekaburan dalam Berbilang Warisan dengan Jenis Bertindih

Warisan berbilang boleh membawa kepada samar-samar panggilan ahli kelas apabila kelas asas yang berbeza mempunyai set tidak bertindih jenis yang berkenaan untuk kaedah polimorfik. Pertimbangkan senario di mana templat kelas asas variadic, Base, mentakrifkan kaedah, foo(), yang hanya boleh digunakan dengan parameter templat yang terkandung dalam pek parameter jenisnya.

Dalam contoh kami:

<code class="cpp">template <typename ... Types>
class Base {
public:
    template <typename T>
    typename std::enable_if<Contains<T, Types ...>::value>::type
    foo() {
        std::cout << "Base::foo()\n";
    }
};
Salin selepas log masuk

Kita boleh memperoleh kelas, Derived, yang mewarisi dua kali daripada Base dengan set jenis tidak bertindih:

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{};</code>
Salin selepas log masuk

Apabila memanggil Derived().foo(), pengkompil tidak boleh menyelesaikan kelas asas mana untuk memanggil foo() daripada, membawa kepada ralat panggilan yang tidak jelas.

Mengapa Pengkompil Tidak Dapat Menyelesaikan Kekaburan

Peraturan gabungan untuk kelas -member lookup menyatakan bahawa jika set pengisytiharan kelas terbitan (dalam kes ini, Derived) kosong, set carian untuk ahli (dalam kes ini, foo) digabungkan daripada semua kelas asas langsung. Walau bagaimanapun, memandangkan kelas asas kami mempunyai set pengisytiharan yang berbeza untuk foo, cantuman adalah samar-samar.

Penyelesaian

Untuk menyelesaikan kekaburan, kami boleh membuat set pengisytiharan Terbitan tidak kosong dengan menambah menggunakan pengisytiharan untuk kaedah foo dalam asas:

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{
    using Base<int, char>::foo;
    using Base<double, void>::foo;
};</code>
Salin selepas log masuk

Menggunakan pengisytiharan membawa ahli daripada kelas asas ke dalam kelas terbitan, dengan berkesan menyediakan Derived dengan dua lebihan foo. Pengkompil kemudian boleh memanggil lebihan beban yang sesuai dengan jelas.

Penyelesaian Alternatif

  • Kelas Pengumpul Asas: Templat kelas ini boleh mengumpul menggunakan pengisytiharan untuk berbilang pangkalan, mengurangkan keperluan untuk pengisytiharan eksplisit.
  • Peluasan Pek dalam C 17: Peluasan pek boleh digunakan untuk memudahkan templat BaseCollector kepada satu baris, menjadikannya lebih ringkas dan cekap untuk menyusun.

Atas ialah kandungan terperinci Bagaimana untuk Menyelesaikan Kekaburan dalam Berbilang Warisan dengan Jenis Bertindih Apabila Memanggil Kaedah Polimorfik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!