包含朋友 class 的循环引用问题
Cyclic Reference issue with includes for friend class
我有 2 个 classes:S 和 R。R 有一个 S 类型的实例。我想让 R 作为朋友 class 来访问 S 私有方法。
不幸的是我无法构建它。请帮我解决这个问题。我尝试了更多方式的前向声明,但没有用。我收到以下错误
R.hpp:12:15: error: ‘n1::n2’ has not been declared
12 | R(n1::n2::Sptr s);
提前致谢!
S.hpp:
#ifndef S_H
#define S_H
#include <memory>
namespace n1 {
namespace n2 {
class S {
friend class c1::R;
int x;
inline void print();
};
using Sptr = std::shared_ptr<S>;
}
}
#endif
S.cpp:
#include "S.hpp"
#include "R.hpp"
namespace n1 {
namespace n2 {
void S::print()
{
std::cout<<"S-print\n";
}
}
}
R.hpp:
#ifndef R_H
#define R_H
#include <memory>
namespace n1 {
namespace c1 {
class S;
struct R {
R(n1::n2::Sptr s);
void r();
n1::n2::Sptr s_;
};
}
}
#endif
R.cpp:
#include "R.hpp"
#include "S.hpp"
namespace n1 {
namespace c1 {
R::R(n1::n2::Sptr s):s_(s)
{}
void R::r() {
s_->print();
}
}
}
main.cpp:
#include <iostream>
#include "R.hpp"
#include "S.hpp"
#include <memory>
int main() {
auto s = std::make_shared<n1::n2::S>();
auto r = std::make_shared<n1::c1::R>(s);
r->r();
//s.print();
return 0;
}
- 删除所有交叉 header 文件包含。 (你似乎已经这样做了)
- 用 header 中的前向声明替换缺失的符号。
- 添加 header 文件包含已删除的 cpp 文件。 (你似乎已经这样做了)
- 在需要时重新定义 shared_ptr 别名。
您可以通过在您的文件中使用以下修改来使程序运行(编译):
S.hpp
#ifndef S_H
#define S_H
#include <memory>
namespace n1
{
namespace c1
{
class R;
}
}
namespace n1 {
namespace n2 {
class S {
friend class c1::R;
int x;
void print();
};
// using Sptr = std::shared_ptr<S>;
}
}
#endif
S.cpp
#include "S.hpp"
//#include "R.hpp"
#include <iostream>
namespace n1 {
namespace n2 {
void S::print()
{
std::cout<<"S-print\n";
}
}
}
R.hpp
#ifndef R_H
#define R_H
#include <memory>
namespace n1
{
namespace n2
{
class S;
using Sptr = std::shared_ptr<S>;
}
}
namespace n1 {
namespace c1 {
class S;
struct R {
R(n1::n2::Sptr s);
void r();
n1::n2::Sptr s_;
};
}
}
#endif
R.cpp
#include "R.hpp"
#include "S.hpp"
namespace n1 {
namespace c1 {
R::R(n1::n2::Sptr s):s_(s)
{}
void R::r() {
s_->print();
}
}
}
上面程序的输出可见here.
我有 2 个 classes:S 和 R。R 有一个 S 类型的实例。我想让 R 作为朋友 class 来访问 S 私有方法。 不幸的是我无法构建它。请帮我解决这个问题。我尝试了更多方式的前向声明,但没有用。我收到以下错误
R.hpp:12:15: error: ‘n1::n2’ has not been declared 12 | R(n1::n2::Sptr s);
提前致谢!
S.hpp:
#ifndef S_H
#define S_H
#include <memory>
namespace n1 {
namespace n2 {
class S {
friend class c1::R;
int x;
inline void print();
};
using Sptr = std::shared_ptr<S>;
}
}
#endif
S.cpp:
#include "S.hpp"
#include "R.hpp"
namespace n1 {
namespace n2 {
void S::print()
{
std::cout<<"S-print\n";
}
}
}
R.hpp:
#ifndef R_H
#define R_H
#include <memory>
namespace n1 {
namespace c1 {
class S;
struct R {
R(n1::n2::Sptr s);
void r();
n1::n2::Sptr s_;
};
}
}
#endif
R.cpp:
#include "R.hpp"
#include "S.hpp"
namespace n1 {
namespace c1 {
R::R(n1::n2::Sptr s):s_(s)
{}
void R::r() {
s_->print();
}
}
}
main.cpp:
#include <iostream>
#include "R.hpp"
#include "S.hpp"
#include <memory>
int main() {
auto s = std::make_shared<n1::n2::S>();
auto r = std::make_shared<n1::c1::R>(s);
r->r();
//s.print();
return 0;
}
- 删除所有交叉 header 文件包含。 (你似乎已经这样做了)
- 用 header 中的前向声明替换缺失的符号。
- 添加 header 文件包含已删除的 cpp 文件。 (你似乎已经这样做了)
- 在需要时重新定义 shared_ptr 别名。
您可以通过在您的文件中使用以下修改来使程序运行(编译):
S.hpp
#ifndef S_H
#define S_H
#include <memory>
namespace n1
{
namespace c1
{
class R;
}
}
namespace n1 {
namespace n2 {
class S {
friend class c1::R;
int x;
void print();
};
// using Sptr = std::shared_ptr<S>;
}
}
#endif
S.cpp
#include "S.hpp"
//#include "R.hpp"
#include <iostream>
namespace n1 {
namespace n2 {
void S::print()
{
std::cout<<"S-print\n";
}
}
}
R.hpp
#ifndef R_H
#define R_H
#include <memory>
namespace n1
{
namespace n2
{
class S;
using Sptr = std::shared_ptr<S>;
}
}
namespace n1 {
namespace c1 {
class S;
struct R {
R(n1::n2::Sptr s);
void r();
n1::n2::Sptr s_;
};
}
}
#endif
R.cpp
#include "R.hpp"
#include "S.hpp"
namespace n1 {
namespace c1 {
R::R(n1::n2::Sptr s):s_(s)
{}
void R::r() {
s_->print();
}
}
}
上面程序的输出可见here.