我有2个班级:
MyString
和LongNumber
。并且 LongNumber
类有一个 Foo
方法,可以访问 private
类的 MyString
字段,也就是说,Foo
方法是 friend
类的 MyString
。所以我在这里写了一些代码:
// File: MyString.h
- - - - - - - - - - - - - -
#pragma once
// default includes with angular brackets
class LongNumber; // forward declaration
class MyString
{
char* symbols;
size_t capacity;
size_t length;
friend void LongNumber::Foo(MyString& str); // <-- error here
// Methods
}
// File: MyString.cpp
- - - - - - - - - - - - - -
// including "MyString.h" and "LongNumber.h" in .cpp to avoid circular dependency
#include "MyString.h"
#include "LongNumber.h"
// default includes with angular brackets
// Implementations
// File: LongNumber.h
- - - - - - - - - - - - - -
#pragma once
// default includes with angular brackets
class MyString; // forward declaration
class LongNumber
{
uint8_t sign;
MyString digits;
void Foo(MyString& str); // supposed to be a friend to the class MyString
// Methods
}
// File: LongNumber.cpp
- - - - - - - - - - - - - -
// including "MyString.h" and "LongNumber.h" in .cpp to avoid circular dependency
#include "MyString.h"
#include "LongNumber.h"
// default includes with angular brackets
void LongNumber::Foo(MyString& str) // supposed to be a friend to the class MyString
{
// some code
}
// other implementations
File: Main.cpp
- - - - - - - - - - - - - -
#include <iostream>
#include "MyString.h"
#include "LongNumber.h"
// #include "LongNumber.h"
// #include "MyString.h"
// reversed order won't help either
int main() {} // empty
我读过有关避免 C++ 中的循环依赖的内容。他们建议您在
.h
文件中转发声明类,并将所有 include
移动到 .cpp
文件中。我已经这样做了,但这对我不起作用。
当我编译这个时,我得到:
...MyString.h(11,26): error C2027: use of undefined type 'LongNumber'
导致此错误的代码行是:
friend void LongNumber::Foo(MyString& str);
编译器不关心我向前声明了类
LongNumber
。从某种意义上来说,它似乎看不到我的其他文件,因为如果我像这样修改 MyString.h
文件:
// File: MyString.h
- - - - - - - - - - - - - -
#pragma once
// default includes with angular brackets
class UnknownClass; // forward declaration, deliberately wrote a name that does not exist
class MyString
{
char* symbols;
size_t capacity;
size_t length;
friend void UnknownClass::Foo(MyString& str); // <-- error here
// Methods
}
错误是一样的:
...MyString.h(11,28): error C2027: use of undefined type 'UnknownClass'
我觉得让编译器知道类
LongNumber
存在并已完成的唯一方法是将#include "LongNumber.h"
放入头文件中,但这是不允许的,因为它会创建循环依赖。
我想要实现的目标可能吗?
您不能通过名称引用不完整类的方法。将
UnknownClass
变为 KnownClass
:
// KnownClass.h
struct MyString;
struct KnownClass {
void foo(const MyString&);
};
// MyString.h
struct MyString {
friend void KnownClass::foo(const MyString&);
};
// KnownClass.cpp
void KnownClass::foo(const MyString&) {
// implementation
}