과 class A : public B
이 B
에서 상속 받았다고 가정 해 보겠습니다. 나는 A
의 메소드를 노출하고자하는데, 이는 B
의 메소드를 호출합니다.Pimpl 관용구에서의 C++ 계승
는 지금은 pimpl 관용구에서 이러한 방법을 노출 할 - 난 정말이 작업을 수행하는 방법을 잘 모르겠어요 :
모두A
및B
별도의 구현 클래스B::impl
을받을 수 있나요 및A::impl : public B::impl
등의 구현이 서로에게서 물려 받습니까? 일반 클래스는 다음 상속하지 않습니다 :class A
및class B
?구현이
private
이기 때문에 가능하지 않습니다.구현은
B::impl
및A::impl
를 서브 클래 싱하지 않지만 노출 된 클래스는class B
및class A : public B
을한다. 그렇다면A::impl
의 메소드는 부모의 메소드를B::impl
에 호출 할 수 있습니까?인수의 포인터를 통해 - 아래 예제를 참조하십시오.
감사
편집 : 여기있는 예제 코드 -이 맞습니까?
test.hpp
#include <iostream>
class B {
private:
class impl;
std::unique_ptr<impl> pimpl;
public:
B();
~B();
B(B&&) = default;
B(const B&) = delete;
B& operator=(B&&);
B& operator=(const B&) = delete;
void my_func() const;
};
class A : public B {
private:
class impl;
std::unique_ptr<impl> pimpl;
public:
A();
~A();
A(A&&) = default;
A(const A&) = delete;
A& operator=(A&&);
A& operator=(const A&) = delete;
void access_my_func();
};
Test.cpp에 당신이 다음 B에서 서브 클래스 경우
#include "test.hpp"
// Implementation of B
class B::impl
{
public:
impl() {};
void impl_my_func() {
std::cout << "impl_my_func" << std::endl;
return;
};
};
// Constructor/Destructor of B
B::B() : pimpl{std::make_unique<impl>()} {};
B::~B() = default;
B& B::operator=(B&&) = default;
// Exposed method of B
void B::my_func() const {
std::cout << "B::my_func" << std::endl;
pimpl->impl_my_func();
return;
};
// Implementation of A
class A::impl
{
public:
impl() {};
void impl_access_my_func(const A& a_in) {
std::cout << "impl_access_my_func" << std::endl;
a_in.my_func();
return;
};
};
// Constructor/Destructor of A
A::A() : pimpl{std::make_unique<impl>()} {};
A::~A() = default;
A& A::operator=(A&&) = default;
// Exposed method of A
void A::access_my_func() {
std::cout << "A::access_my_func" << std::endl;
pimpl->impl_access_my_func(*this);
return;
};
// Later in the main.cpp file
int main() {
// Make an object
A my_A_object;
my_A_object.access_my_func();
return 0;
};
[고려] (http://stackoverflow.com/q/825018/7571258) pimpl이 실제로 사용 사례에 적합한 관용구라면.순수 가상 기본 클래스는 구문 상 오버 헤드가 적은 대안이 될 수 있습니다. 특히 상속이 관련 될 때 그렇습니다. – zett42
고마워요! 나는 이것에 대해 생각하지 않았다. 이 프로젝트의 최종 목표는 API이므로, pimpl은 구현 세부 정보를 숨기고 향후 변경 후 이전 버전과의 호환성을 보장하는 인기있는 방법입니다. 순수한 가상 기본 클래스를 동일한 목적으로 사용할 수 있는지 확실하지 않습니다. – Kurt
다음과 같이 사용할 수 있습니다. [이 질문에 대한 예제] (http://stackoverflow.com/q/3092444/7571258)를 참조하십시오. ABI 호환성에 문제가있을 수 있습니다. [이 답변] (http://stackoverflow.com/a/2330745/7571258)에 대한 의견을 참조하십시오. – zett42