在pimpl习惯用法中无效使用不完整类型错误

时间:2018-08-12 15:46:51

标签: c++ design-patterns pimpl-idiom

foo.h

#include"fooImpl.h"

    class foo
    { 
        private:
            class fooImpl; 
            std::unique_ptr <fooImpl> foo_imple;
        public:
            void bar();  
    };

fooImpl.h

#include "foo.h"

    class foo::fooImpl 
    {
        public: 
            void api();  
    };

foo.cpp

#include "foo.h"

void foo::bar()
{
    foo_imple->api();
}

fooImpl.cpp

#include"foo.h"
#include"fooImpl.h"

void foo::fooImpl::api()       
{   
    cout << "bar"; 
}

出现以下错误:

  

错误:无效使用了不完整类型'class foo :: fooImpl'
    foo_imple-> bar();

     

注意:“ foo :: fooImpl类”的前向声明
     fooImpl类;

无法发现此pimpl实现有什么问题。错误似乎是由于缺少一些声明。

2 个答案:

答案 0 :(得分:2)

foo_imple->bar();调用fooImpl.h的类声明应该可用。尽管对于foo类声明,不需要包含fooImpl.h

答案 1 :(得分:2)

这是更典型的:

foo.h

class foo
{ 
    private:
        class fooImpl;
        std::unique_ptr <fooImpl> foo_imple;

    public:
        void bar();
        // Non-inline destructor so we don't need a definition for fooImpl
        ~foo();
};

foo.cpp

#include "foo.h"

class foo::fooImpl
{
    public:
        void api()
        {
            cout << "bar";
        }
};

void foo::bar()
{
    foo_imple->api();
}

foo::~foo() = default;

请注意,现在您无需向fooImpl的用户公开有关foo的任何内容-该类已完全隐藏。如果仅在fooImpl源文件中使用foo.cpp,还可以避免使用其他头文件和cpp文件,否则可以将其及其方法定义内联在fooImpl.h中,只需要包含在foo.cpp中。