>백엔드 개발 >C++ >클래스 템플릿을 상속할 때 기본 클래스의 공용 멤버가 보이지 않는 이유는 무엇이며, 이 문제에 대한 해결책은 무엇입니까?

클래스 템플릿을 상속할 때 기본 클래스의 공용 멤버가 보이지 않는 이유는 무엇이며, 이 문제에 대한 해결책은 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-11-02 15:13:30338검색

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

상속된 클래스 템플릿에서 공개 멤버 숨김 및 코드 팽창 방지

객체 지향 프로그래밍은 보호된 클래스 멤버와 공개 클래스 멤버의 상속에 의존합니다. 템플릿이 아닌 환경에서는 이 상속이 간단합니다. 그러나 클래스 템플릿을 도입할 때 근본적인 문제가 발생합니다. 기본 클래스의 공용 멤버가 파생 클래스 템플릿에 보이지 않게 됩니다.

문제

다음 예를 고려하세요. :

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

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

이 코드를 템플릿화할 때 CBase의 Fn1() 멤버는 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>

솔루션

이 문제를 해결하기 위한 다양한 솔루션이 있습니다.

솔루션 1(자세한 접두사):

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

그러나 이 접근 방식은 여러 멤버를 참조할 때 과도한 코드 팽창을 초래합니다.

솔루션 2(장황한 "this->" 접두사):

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

솔루션 1과 유사하지만 약간 덜 장황합니다.

솔루션 3(문 사용):

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

추가 접두사 없이 CBase 멤버에 직접 액세스할 수 있습니다.

솔루션 4(허용 모드):

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

엄격한 C 규정 준수를 비활성화하여 문제를 해결하지만 이식성 문제가 발생할 수 있습니다.

더 나은 솔루션

솔루션 3은 다른 것보다 깔끔하지만 여전히 반복적인 "using" 문이 필요합니다. 매크로는 이를 단순화할 수 있습니다.

<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>

파생 클래스에서:

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

이 접근 방식은 코드 팽창과 중복을 크게 줄입니다.

위 내용은 클래스 템플릿을 상속할 때 기본 클래스의 공용 멤버가 보이지 않는 이유는 무엇이며, 이 문제에 대한 해결책은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.