c++ - 类外的前向声明有效,但嵌套时无效
问题描述
假设我有两个班级A
并B
使用pimpl
成语。A
提供公共 API,持有指向B
. B
在内部进行前向声明时出现编译错误A
,但在外部声明时却没有。
为什么后者不起作用?在这两种情况下,我b.hpp
在a.cpp
调用任何B
.
课外前向声明A
此示例正常工作。
文件a.hpp
:
#ifndef _A_
#define _A_
#include <memory>
class B; // forward declaration, defined in a.cpp
class A {
public:
A();
~A();
void Hi();
private:
std::unique_ptr< B > b_;
};
#endif
文件a.cpp
:
#include "b.hpp"
#include "a.hpp"
A::A() : b_( std::make_unique< B >() ) { }
A::~A() { }
void
A::Hi() {
this->b_->Hi();
}
文件b.hpp
:
#ifndef _B_
#define _B_
class B {
public:
void Hi();
};
#endif
文件b.cpp
:
#include "b.hpp"
#include <iostream>
void
B::Hi() {
std::cout << "Hello World!" << std::endl;
}
驱动文件hello.cpp
:
#include "a.hpp"
int main() {
A a;
a.Hi();
return 0;
}
编译:g++ hello.cpp a.cpp b.cpp -std=c++14
类内前向声明A
在这里,我正在移动 inside 的前向B
声明A
。
文件a.hpp
:
#ifndef _A_
#define _A_
#include <memory>
class A {
public:
A();
~A();
void Hi();
private:
class B; // forward declaration, defined in a.cpp
std::unique_ptr< B > b_;
};
#endif
我收到以下编译错误:
a.cpp: In member function ‘void A::Hi()’:
a.cpp:9:10: error: invalid use of incomplete type ‘class A::B’
this->b_->Hi();
^
In file included from a.cpp:2:0:
a.hpp:12:8: error: forward declaration of ‘class A::B’
class B;
^
In file included from /usr/include/c++/4.9/memory:81:0,
from a.hpp:4,
from a.cpp:2:
/usr/include/c++/4.9/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = A::B; _Args = {}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<A::B>]’:
a.cpp:4:36: required from here
/usr/include/c++/4.9/bits/unique_ptr.h:765:69: error: invalid use of incomplete type ‘class A::B’
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
^
In file included from a.cpp:2:0:
a.hpp:12:8: error: forward declaration of ‘class A::B’
class B;
^
In file included from /usr/include/c++/4.9/memory:81:0,
from a.hpp:4,
from a.cpp:2:
/usr/include/c++/4.9/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = A::B]’:
/usr/include/c++/4.9/bits/unique_ptr.h:236:16: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A::B; _Dp = std::default_delete<A::B>]’
a.cpp:4:36: required from here
/usr/include/c++/4.9/bits/unique_ptr.h:74:22: error: invalid application of ‘sizeof’ to incomplete type ‘A::B’
static_assert(sizeof(_Tp)>0,
解决方案
这是因为您没有声明相同的class B
. B
在您的第二个示例中被声明为嵌套类。它具有范围A::
(因为它实际上被命名为 class A::B
)。但是随后您尝试将其用作::B
(如在全局范围内)。
这从错误消息中非常明显:
错误:无效使用不完整类型 '<strong>class A::B'</p>
这行不通。向前声明class B
外部A
是实现这一点的正确方法。
推荐阅读
- r - 如何使用相同的函数按行比较矩阵列表
- jquery - jQuery 的“选择选项”不适用于移动设备和触摸设备
- java - Api Level 24 无法录制他人的声音。权限没有问题
- php - 使用 PEEK 获取 PHP Horde imap
- javascript - reactJS 如何为数据库中的数据添加搜索过滤器
- javascript - CORS 的好选择
- android - 将 kotlin 插件更新到 1.2.51 后无法运行应用程序
- docker - 调用 redis-trib 时启动 Redis 集群挂起
- javascript - 访问绑定到底层类的 DOM 节点和函数
- dapper-contrib - Dapper.Contrib 支持复合主键