Pimpl Idiom 的嵌套名称说明符中使用的不完整类型
Incomplete type used in nested name specifier for Pimpl Idiom
我遇到以下代码的错误
incomplete type ‘Foo::Pimpl’ used in nested name specifier
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
方法的签名。
您可以在其中访问 Foo::Pimpl
详细信息的唯一文件是 Foo.cpp,即定义它的文件。
您可能无法在 AnotherFoo.cpp 中访问它。
您的选择是:
更改 AnotherFoo::methodAnotherFoo
的实现以仅使用 Foo
的 public 接口。
将 AnotherFoo::methodAnotherFoo
的实施移动到 Foo.cpp。
如果 AnotherFoo.cpp 需要直接访问实现 object 它将不得不查看该类型的定义,没有办法解决这个问题。也许添加一个 "detail/foo.h" header 供内部使用。
您的 Pimpl 实现不正确。当您尝试直接从 methodAnotherFoo
访问它们时,它应该隐藏详细信息。因此,您应该将实现细节设为私有并提供 public 代理方法来操作存储的实现:
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);
}
我找到的一个解决方案是将 Pimpl 实现移至 AnotherFoo.cpp
我遇到以下代码的错误
incomplete type ‘Foo::Pimpl’ used in nested name specifier
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
方法的签名。
您可以在其中访问 Foo::Pimpl
详细信息的唯一文件是 Foo.cpp,即定义它的文件。
您可能无法在 AnotherFoo.cpp 中访问它。
您的选择是:
更改
AnotherFoo::methodAnotherFoo
的实现以仅使用Foo
的 public 接口。将
AnotherFoo::methodAnotherFoo
的实施移动到 Foo.cpp。
如果 AnotherFoo.cpp 需要直接访问实现 object 它将不得不查看该类型的定义,没有办法解决这个问题。也许添加一个 "detail/foo.h" header 供内部使用。
您的 Pimpl 实现不正确。当您尝试直接从 methodAnotherFoo
访问它们时,它应该隐藏详细信息。因此,您应该将实现细节设为私有并提供 public 代理方法来操作存储的实现:
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);
}
我找到的一个解决方案是将 Pimpl 实现移至 AnotherFoo.cpp