Pimpl Idiom的嵌套名称说明符中使用的不完整类型

时间:2017-12-12 21:25:07

标签: c++ c++11 c++-standard-library pimpl-idiom

我对以下代码有错误

  

在嵌套名称说明符

中使用的不完整类型'Foo :: Pimpl'

AnotherFoo.hpp

struct AnotherFoo {
    void methodAnotherFoo(Foo &);
};

AnotherFoo.cpp

#include "Foo.hpp"
#include "AnotherFoo.hpp"

void AnotherFoo::methodAnotherFoo(Foo &foo) {
    // here i want to save the function pointer of methodPimpl(), std::function for ex:
    std::function<void(void)> fn = std::bind(&Foo::Pimpl::methodPimpl, foo._pimpl); // <-- Here i am getting the error
}

Foo.hpp

struct Foo {
    Foo();
    class Pimpl;
    std::shared_ptr<Pimpl> _pimpl;
};

Foo.cpp中

#include "Foo.hpp"

struct Foo::Pimpl {
    void methodPimpl(void) {}    
};

Foo::Foo() : _pimpl(new Pimpl) {}

的main.cpp

#include "Foo.hpp"
#include "AnotherFoo.hpp"

int main() {
    Foo foo;
    AnotherFoo anotherFoo;
    anotherFoo.methodAnotherFoo(foo);
}

有没有人有一个很好的解决方案来解决这个问题?

我想要实现的主要目标是保持methodAnotherFoo方法的签名隐藏在头文件中。

4 个答案:

答案 0 :(得分:4)

您可以访问while详细信息的唯一文件是Foo.cpp,它是定义它的文件。

您可能无法在AnotherFoo.cpp中访问它。

您的选择是:

  1. Foo::Pimpl的实施更改为仅使用AnotherFoo::methodAnotherFoo的公共界面。

  2. Foo的实现移至Foo.cpp。

答案 1 :(得分:0)

如果AnotherFoo.cpp需要直接访问实现对象,它将不得不看到该类型的定义,没有办法解决这个问题。也许添加一个“detail / foo.h”标题,供内部使用。

答案 2 :(得分:0)

您的Pimpl实施不正确。当您尝试直接从methodAnotherFoo访问详细信息时,它应隐藏详细信息。因此,您应该将实现细节设为私有,并提供公共代理方法来操作存储的实现:

class Foo
{
    public: Foo();

    public: void method(void);

    private: class Pimpl;
    private: std::shared_ptr<Pimpl> _pimpl;
};

// Foo.cpp
struct Foo::Pimpl
{
    void methodPimpl(void) {}    
};

Foo::Foo() : _pimpl(new Pimpl) {}

void Foo::method(void) {_pimpl->method();}

更改代码的其余部分以利用这些代理方法,而不是挖掘实现细节:

void AnotherFoo::methodAnotherFoo(Foo &foo)
{
    std::function<void(void)> fn = std::bind(&Foo::method, foo);
}

答案 3 :(得分:-1)

我找到的一个解决方案是将Pimpl实现移动到AnotherFoo.cpp