C++ 继承期间受保护成员的pimpl
我在派生类使用的`基类hpp文件中声明了大量受保护的成员函数。我的想法是从头文件中删除它们,以减少编译依赖性。我也考虑过对受保护的成员使用pimpl方法 我在基类cpp文件中定义了一个Impl类,并将所有受保护的函数移到Impl类中。此外,我在基类头文件中做了一个Impl类作为受保护成员的转发声明C++ 继承期间受保护成员的pimpl,c++,oop,inheritance,protected,pimpl-idiom,C++,Oop,Inheritance,Protected,Pimpl Idiom,我在派生类使用的`基类hpp文件中声明了大量受保护的成员函数。我的想法是从头文件中删除它们,以减少编译依赖性。我也考虑过对受保护的成员使用pimpl方法 我在基类cpp文件中定义了一个Impl类,并将所有受保护的函数移到Impl类中。此外,我在基类头文件中做了一个Impl类作为受保护成员的转发声明 protected: class Impl; Impl* impl_; 但在这样做时,当我使用impl_uu从派生类调用受保护函数时,派生类编译中出现以下错误: error: inv
protected:
class Impl;
Impl* impl_;
但在这样做时,当我使用impl_uu从派生类调用受保护函数时,派生类编译中出现以下错误:
error: invalid use of incomplete type ‘class Base::Impl’
if (false == impl_->EncodeMMMsgHeader(mm_msg_header_)) {
error: forward declaration of ‘class Base::Impl’
我认为出现错误是因为在编译器需要类的上下文信息的任何情况下都不能使用前向声明,编译器也不能只告诉它一点点类的信息
有什么办法可以克服上述问题吗?如果没有,那么谁能给我推荐一个更好的方法来实现我的目标。您可以添加一个层来减少依赖性: 从 然后 MyClass.h
#包括
类MyClassProtectedStuff;
类MyClass
{
公众:
~MyClass();
/*...*/
受保护的:
const MyClassProtectedStuff&GetProtected()const;
MyClassProtectedStuff&GetProtected();
私人:
结构Pimpl;
std::唯一的\u ptr impl;
std::unique_ptr protectedData;//可能在Piml中。
};
然后派生类应该包含这两个头,而常规类只包含MyClass.h受保护和虚拟方法是接口的一部分,不应该隐藏在pimpl中。不确定@Jarod42,受保护的虚拟函数通常是实现的一部分,几乎从来都不是接口的一部分。@EduardRostomyan:派生类可以查看并使用受保护的
数据,并且可以覆盖每个虚拟(非最终)方法。同意,但这并不能使其成为类接口的一部分,相反,它使它们成为实现的一部分我还有另一个目的,就是从头文件中删除受保护的成员函数。因为我必须在大量其他文件中包含“MyClass.h”头文件,这些文件不需要这些受保护的内容。虽然你的想法很管用,但它会挫败我上述同样重要的目的。
#include "lot_of_dependencies"
#include <memory>
class MyClass
{
public:
~MyClass();
/*...*/
protected:
/* Protected stuff */
private:
struct Pimpl;
std::unique_ptr<Pimpl> impl;
};
#include "lot_of_dependencies"
class MyClassProtectedStuff
{
public:
/* Protected stuff of MyClass */
private:
// MyClass* owner; // Possibly back pointer
};
#include <memory>
class MyClassProtectedStuff;
class MyClass
{
public:
~MyClass();
/*...*/
protected:
const MyClassProtectedStuff& GetProtected() const;
MyClassProtectedStuff& GetProtected();
private:
struct Pimpl;
std::unique_ptr<Pimpl> impl;
std::unique_ptr<MyClassProtectedStuff> protectedData; // Might be in Piml.
};