Shibir Basak
Shibir Basak

Reputation: 73

invalid use of incomplete type error in 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"; 
}

Getting the following error:

error: invalid use of incomplete type 'class foo::fooImpl'
foo_imple->bar();

note: forward declaration of 'class foo::fooImpl'
class fooImpl;

Not able to find out whats wrong with this pimpl implementation. Error looks like due to some declaration missing.

Upvotes: 1

Views: 1750

Answers (2)

Chris Hunt
Chris Hunt

Reputation: 4030

This is more typical:

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;

Notice that now you don't need to expose anything about the fooImpl to users of foo - the class is completely hidden. You also avoid having additional header and cpp files if fooImpl is only used in your foo.cpp source file, otherwise you could put it and its method definitions inline in a fooImpl.h that only needs to be included in foo.cpp.

Upvotes: 4

user7860670
user7860670

Reputation: 37599

In order to call foo_imple->bar(); class declaration from fooImpl.h should be available. While for foo class declaration there is no need to include fooImpl.h

Upvotes: 3

Related Questions