类外的前向声明有效,但嵌套时无效

时间:2018-06-10 19:08:54

标签: c++ forward-declaration pimpl-idiom

假设我有两个使用A成语的Bpimpl类。 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;
}

编译:{{1​​}}

g++ hello.cpp a.cpp b.cpp -std=c++14

中的前向声明

我在A内移动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

1 个答案:

答案 0 :(得分:3)

这是因为你没有声明相同的class B。第二个示例中的B被声明为嵌套类。它具有范围A::(因为它实际上命名为类A::B)。但是,您尝试将其用作::B(如在全局范围内)。

从错误消息中可以看出这一点:

  

错误:无效使用不完整类型' A类:: B '

这不起作用。正确声明class B A外部是实现此目的的正确方法。