接口类产生“使用未定义类型”

时间:2017-07-01 15:15:06

标签: c++ c++11

ALL,

我在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;
};

不幸的是,此代码会产生错误:

Use of undefined type 'Foo::Impl'

尝试转发声明Database :: Impl会导致另一个编译器错误。

那么解决它的最佳方法是什么?

所有这些都在一个头文件中。

编辑:

我想我可以将函数放在实际的实现类中,但我真的想要消除代码重复。但是看起来我没有别的选择。

3 个答案:

答案 0 :(得分:2)

pimpl->m_string;需要pimpl(即Foo::Impl)的类型为complete type,但稍后会对其进行定义;只有前向声明是不够的,Foo::Impl之前需要定义。

我认为您正在尝试实现PImpl idiom,这通常用于减少编译时依赖性;所以你应该将Foo::ImplFoo::GetMember的定义移到实现文件,比如

// 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; }

答案 1 :(得分:1)

  

那么解决它的最佳方法是什么?

GetMember()的定义移至单独的翻译单元(.cpp文件)。

您也应该在struct Foo::Impl的声明和实施中这样做。这至少是Pimpl Idiom的全部目的。

答案 2 :(得分:-1)

ALL,

显然有一个更简单的解决方案:在Impl结构中移动函数。

谢谢大家阅读。