Igor
Igor

Reputation: 6255

Interface class produce "Use of undefined type"

ALL,

I have a following code in the foo.h:

class __declspec(dllexport) Foo
{
protected:
    struct Impl;
    Impl *pimpl;
public:
    std::wstring &GetMember() { return pimpl->m_string; };
};

struct Foo::Impl
{
    std::wstring m_string;
};

Unfortunately this code produces an error:

Use of undefined type 'Foo::Impl'

Trying to forward declare Database::Impl results in another compiler error.

So what is the best way to fix it?

All this is in one header file.


EDIT:

I guess I could put the function in the actual implementations classes, but I really wanted to eliminate code duplication. However it looks like I won't have any other choice.

Upvotes: 0

Views: 477

Answers (3)

Igor
Igor

Reputation: 6255

ALL,

Apparently there is an easier solution: move the function inside the Impl structure.

Thank you all for reading.

Upvotes: -1

songyuanyao
songyuanyao

Reputation: 172934

pimpl->m_string; needs the type of pimpl (i.e. Foo::Impl) to be a complete type, but it's defined later; only forward declaration is not sufficient, Foo::Impl needs to be defined before.

And I suppose you're trying to implement the PImpl idiom, which is usually used to to reduce compile-time dependencies; so you should move the definition of Foo::Impl and Foo::GetMember to an implementation file, like

// Foo.h
class Foo
{
protected:
    struct Impl;
    Impl *pimpl;
public:
    std::wstring &GetMember();
};

// Foo.cpp
#include "Foo.h"
struct Foo::Impl
{
    std::wstring m_string;
};

// define Foo::GetMember after the definition of Foo::Impl
std::wstring &Foo::GetMember() { return pimpl->m_string; }

Upvotes: 2

user8238559
user8238559

Reputation:

So what is the best way to fix it?

Move the definition of GetMember() out to a separate translation unit (.cpp file).

You should do so as well for the declaration and implementation of struct Foo::Impl. That's at least the whole purpose of the Pimpl Idiom.

Upvotes: 1

Related Questions