如何转发声明第三方结构
How to forward declare third-party struct
在我的原始代码中,我引用了ClassOne
头文件中的第三方.H,一切都很好。现在,我收到了一个新的要求,不允许我引用ClassOne
头文件中的第三方.H。这样,我的代码的使用者(即ClassOne)就不必间接包含第三方.H文件。我试过以下修改,但不起作用。
这是示例代码:
// third_party.h
struct PPP
{
int x;
int y;
}; // without default constructor
// Original code!
//////////////////////////////////////////////
// ClassOne.h // my class
#include <third_party.h> // refer to the .H in header file
namespace X
{
class ClassOne
{
...
private:
boost::scoped_ptr<PPP> m_scpPPP;
};
}
// ClassOne.cpp
#include <third_party.h>
namespace X
{
ClassOne::ClassOne()
{
m_scpPPP.reset( new PPP() ); // fine
}
...
}
// Modified code!
==========================================================
// ClassOne.h
struct PPP; // error C2371: 'PPP' : redefinition; different basic types
namespace X
{
class ClassOne
{
...
private:
boost::scoped_ptr<PPP> m_scpPPP;
};
}
// ClassOne.cpp
#include <third_party.h>
namespace X
{
ClassOne::ClassOne()
{
m_scpPPP.reset( new PPP() ); // now see errors.
// error C2512: 'PPP' : no appropriate default constructor available
}
...
}
问题1>我应该在哪里转发声明第三方结构类型PPP
?
问题2>为什么编译器现在抱怨PPP没有默认构造函数?
实例化类型不完整的模板不是标准行为,因此它不应该在boost::scoped_ptr
中工作。
话虽如此,unique_ptr
有一个特殊的规则,允许采用不完全类型。如果你使用它(而不是boost::scoped_ptr
),那么它是这样做的:
// forward declaration of PPP, assuming c++ header
struct PPP;
namespace X
{
class ClassOne
{
...
private:
std::unique_ptr<PPP> m_scpPPP;
};
}
简单地说:那行不通。由于您在ClassOne中使用PPP(而不是PPP*),编译器需要知道此时的大小,因此需要来知道PPP的定义。要在公共.h文件中隐藏PPP,您需要做更多的操作。一种可能的解决方案是将实现类隐藏在另一个类后面。另一种方法是只在类声明中引用PPP*(尽管这会使scoped_ptr<>的使用变得有点毫无意义)。
编译器期望有一个默认构造函数,因为他假定有一个。他也需要这个类的定义来称之为"新"。您可以通过将ctor的实现移动到.cpp文件来解决此问题,可以在其中包含thirdParty.h。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- #ifdef和未声明的标识符
- 没有显式声明的int[]中的foreach
- 在基于范围的for循环中使用结构化绑定声明
- 在将变量声明为引用时,堆在释放后使用
- C++:无法访问声明的受保护成员
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 在函数内部的声明中初始化数组,并在外部使用它
- 第三方库抱怨MAXPATHLEN没有在一个项目中声明,但在其他项目中没有声明
- 如何转发声明第三方结构