Rumah > pembangunan bahagian belakang > C++ > Mengapakah ahli awam kelas asas menjadi tidak kelihatan apabila mewarisi templat kelas, dan apakah penyelesaian kepada masalah ini?

Mengapakah ahli awam kelas asas menjadi tidak kelihatan apabila mewarisi templat kelas, dan apakah penyelesaian kepada masalah ini?

Susan Sarandon
Lepaskan: 2024-11-02 15:13:30
asal
332 orang telah melayarinya

Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?

Mengelakkan Halimunan Ahli Awam dan Pembengkakan Kod dalam Templat Kelas Diwarisi

Pengaturcaraan berorientasikan objek bergantung pada warisan ahli kelas yang dilindungi dan awam. Dalam persekitaran bukan templat, warisan ini adalah mudah. Walau bagaimanapun, apabila memperkenalkan templat kelas, isu asas timbul: ahli awam kelas asas menjadi tidak kelihatan kepada templat kelas terbitan.

Masalahnya

Pertimbangkan contoh berikut :

<code class="cpp">class CBase
{
public:
    int Fn1(void) { ... }
};

class CDerived : public CBase
{
public:
    int FnSum(void) { ... CBase::Fn1(); ... }
};</code>
Salin selepas log masuk

Apabila membuat templat kod ini, ahli Fn1() CBase hilang daripada perspektif CDerived:

<code class="cpp">template<unsigned int BYTES>
class CBase
{
public:
    int Fn1(void) { ... }
};

template<unsigned int BYTES>
class CDerived : public CBase<BYTES>
{
public:
    int FnSum(void) { ... Fn1(); ... } // Error: Fn1 not found!
};</code>
Salin selepas log masuk

Penyelesaian

Pelbagai penyelesaian wujud untuk menangani isu ini:

Penyelesaian 1 (Awalan Verbose):

<code class="cpp">int FnSum(void) {
    return CBase<BYTES>::Fn1() + CBase<BYTES>::Fn2() + CBase<BYTES>::Arr[0];
}</code>
Salin selepas log masuk

Walau bagaimanapun, pendekatan ini memperkenalkan bloat kod yang berlebihan apabila merujuk berbilang ahli.

Penyelesaian 2 (Awalan Verbose "ini->"):

<code class="cpp">int FnSum(void) {
    return this->Fn1() + this->Fn2() + this->Arr[0];
}</code>
Salin selepas log masuk

Serupa dengan Penyelesaian 1, tetapi kurang bertutur kata.

Penyelesaian 3 (Menggunakan Pernyataan):

<code class="cpp">using CBase<BYTES>::Arr;
using CBase<BYTES>::Fn1;
using CBase<BYTES>::Fn2;</code>
Salin selepas log masuk

Ini membenarkan akses terus kepada ahli CBase tanpa awalan tambahan.

Penyelesaian 4 (Mod Permisif):

<code class="cpp">// Compiler flags: /permissive- (MSVC), -fpermissive (GCC/Cl), -fno-implicit-templates (Clang)</code>
Salin selepas log masuk

Melumpuhkan pematuhan C yang ketat, menyelesaikan isu tetapi mungkin menimbulkan kebimbangan mudah alih.

Penyelesaian yang Lebih Baik

Sementara Penyelesaian 3 adalah lebih bersih daripada yang lain, ia masih memerlukan pernyataan "menggunakan" berulang. Makro boleh memudahkan perkara ini:

<code class="cpp">#include <boost/preprocessor.hpp>

#define USING_ONE(r, base, member) using base::member;

#define USING_ALL(base, ...) BOOST_PP_SEQ_FOR_EACH(USING_ONE, base, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

#define USING_CBASE(param) USING_ALL(CBase<param>, Arr, Fn1, Fn2, Fn3, Fn4, Fn5)</code>
Salin selepas log masuk

Dalam kelas terbitan:

<code class="cpp">USING_CBASE(BYTES); // Makes all mentioned CBase members directly accessible</code>
Salin selepas log masuk

Pendekatan ini mengurangkan pembekuan dan penduaan kod dengan ketara.

Atas ialah kandungan terperinci Mengapakah ahli awam kelas asas menjadi tidak kelihatan apabila mewarisi templat kelas, dan apakah penyelesaian kepada masalah ini?. 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