前置声明,不完全类型。

3

我遇到了

不允许使用不完整的类型

错误。显然,我不懂得如何使用前置声明。我知道不能在头文件中使用方法,但在实现中可以吗?

这是代码:

Foo.h:

#pragma once

class Bar;

class Foo {
    const Bar &mBar;

public:
    Foo(const Bar &bar);

    int getVal() const;
};

Foo.cpp:

#include "Foo.h"

Foo::Foo(const Bar &bar) : mBar(bar) {}

int Foo::getVal() const {
    return mBar.getVal();
}

Bar.h:

#pragma once
class Bar {
public:
    Bar();

    int getVal();
};

Bar.cpp:

#include "Bar.h"

Bar::Bar() {}

int Bar::getVal() {
    return 5;
}

mBar.getVal()是导致错误的原因。然而,它在实现文件中。这也不允许吗?

2个回答

3

在文件Foo.cpp中包含头文件Bar.h

Foo.cpp:

#include "Foo.h"
#include "Bar.h"

Foo::Foo(const Bar &bar) : mBar(bar) {}

int Foo::getVal() const {
    return mBar.getVal();
}

或者在头文件Foo.h中包含头文件Bar.h

Foo.h:

#pragma once
#include "Bar.h"

class Foo {
    const Bar &mBar;

public:
    Foo(const Bar &bar);

    int getVal() const;
};

请注意,函数Bar::getVal必须具有const限定符。

int getVal() const;

否则,你将会得到一个编译错误,因为这个非常量函数被类Foo的一个常量函数所调用。
int Foo::getVal() const {
    return mBar.getVal();
    //     ^^^^^^^^^^^ 
}

2
从编译器的角度来思考。当编译源文件Foo.cpp时,遇到语句mBar.getVal(),它并不知道mBar的成员是什么!它只知道mBar是一个指向const Bar对象的引用。但是如果没有将Bar类定义暴露给编译器,就无法访问它的成员。
通常,您可以在头文件中进行前向声明,以避免引入过多的头文件(如果头文件是外部可见API的一部分,则这很重要)。在源文件中,您应该包含包含类定义的头文件;在本例中为Bar.h

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接