【发布时间】:2017-03-25 19:39:21
【问题描述】:
假设我有一个class B 和一个继承自B 的class A : public B。我要暴露A的方法,调用B中的一些方法。
现在我想在 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中父级的方法呢?通过参数中的指针 - 请参见下面的示例。
谢谢
编辑:这是一个示例代码 sn-p - 这是正确的吗?
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
#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;
};
【问题讨论】:
-
Consider 如果 pimpl 真的是您的用例的正确习惯用法。纯虚拟基类可能是一种语法开销较小的替代方案,尤其是在涉及继承时。
-
谢谢!我没有想过这个。这个项目的最终目标是一个 API,所以我读到 pimpl 是隐藏实现细节并确保未来更改后向后兼容的流行方法。我不确定纯虚拟基类是否可以用于相同目的。
-
可以这样使用,见this question的第一个例子。不过,ABI 兼容性可能存在问题。见评论this answer。
标签: c++ inheritance pimpl-idiom