#include <iostream>
#include <memory>
#include <cstdlib>
class IBase
{
public:
IBase() = default;
virtual ~IBase() = default;
virtual void f1() = 0;
};
class IDerived
{
public:
IDerived() = default;
virtual ~IDerived() = default;
virtual void f2() = 0;
};
class BaseImpl : public IBase
{
public:
BaseImpl() = default;
virtual ~BaseImpl() override = default;
virtual void f1() override { /* serious code */}
};
class DerivedImpl : public BaseImpl, public IDerived
{
public:
DerivedImpl() = default;
virtual ~DerivedImpl() override = default;
virtual void f2() override { /* serious code */}
};
class Base : public IBase
{
public:
Base() : m_impl(std::make_shared<BaseImpl>()) {}
virtual ~Base() override = default;
virtual void f1() override { m_impl->f1(); }
protected:
Base(const std::shared_ptr<BaseImpl>& impl) : m_impl(impl) {}
std::shared_ptr<BaseImpl> m_impl;
};
class Derived : public Base, public IDerived
{
public:
Derived() : Base(std::make_shared<DerivedImpl>()) {}
virtual ~Derived() override = default;
virtual void f2() override { impl()->f2(); }
private:
std::shared_ptr<DerivedImpl> impl() { return std::dynamic_pointer_cast<DerivedImpl>(m_impl); }
};
int main()
{
Base base;
base.f1();
Derived derived;
derived.f1();
derived.f2();
std::cin.sync();
std::cin.get();
return EXIT_SUCCESS;
}
它有效,但看起来很奇怪我可能会放弃pimpl。
答案 0 :(得分:2)
想象一下你的Base定义如下:
class Base {
public:
Base();
virtual ~Base();
virtual void f1();
protected:
class Impl;
Impl *p_impl; // or shared_ptr, or unique_ptr, or whatever you like.
};
请注意,Base::Impl
没有定义任何内容。这是PIMPL习惯用语中非常重要的一部分,因为您可能必须使用Impl类中的元素,这些元素需要#include
- 您不希望包含在标题类中的内容。
派生类看起来像这样:
class Derived: public Base {
public:
Derived();
~Derived();
virtual void f1(); // or not, depends
virtual void f2();
protected:
class Impl2;
Impl2 *p_impl2; // note that Derived::Impl2 might inherit from Base::Impl
};
这仍然隐藏了Base
和Derived
中Base::Impl
和Derived::Impl2
的实施细节,同时让您完全自由地以任何方式实施Derived
你喜欢(包括继承)。
答案 1 :(得分:1)
您的Impl
类应该只包含私有变量和方法。
不要在那里放置任何需要儿童课程的东西。对Impl
类进行子类化是错误的C ++方法,因为这会破坏这种模式的目的。