【问题标题】:invalid use of incomplete type error in pimpl idiom在 pimpl idiom 中无效使用不完整类型错误
【发布时间】:2019-01-19 11:28:56
【问题描述】:

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();

注意:'class foo::fooImpl'的前向声明
类 fooImpl;

无法找出这个 pimpl 实现有什么问题。错误似乎是由于缺少某些声明。

【问题讨论】:

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


【解决方案1】:

为了从fooImpl.h 调用foo_imple-&gt;bar(); 类声明应该可用。而对于foo 类声明,则无需包含fooImpl.h

【讨论】:

  • 那么,您建议进行哪些修改?将 fooImpl.h 添加到 foo.cpp 并从 foo.h 中删除 #include"fooImpl.h"?
  • @ShibirBasak 完全正确。
  • 成功了!谢谢。
  • 如果fooImpl 有任何重要的析构函数,此修复不起作用。请参阅@ChrisHunt 的答案和stackoverflow.com/q/8595471/103167 以获取修复。
  • 得到这个,当在 api() 中使用断言时 --> /usr/include/c++/6.2.0/bits/unique_ptr.h:74:22: 错误:'sizeof' 的无效应用不完整类型 'foo::fooImpl' static_assert(sizeof(_Tp)>0, ^
【解决方案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;

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

【讨论】:

  • 更好:foo::~foo() = default;(在同一个位置,不在类内)但是是的,控制析构函数定义非常必要,如此处所述:stackoverflow.com/q/8595471/103167
  • @ChrisHunt 就我而言,我必须将 impl 移动到单独的文件中。这是因为项目的所有权/模块化限制。
猜你喜欢
  • 2015-05-01
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多