包含朋友 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;
}

 
  1. 删除所有交叉 header 文件包含。 (你似乎已经这样做了)
  2. 用 header 中的前向声明替换缺失的符号。
  3. 添加 header 文件包含已删除的 cpp 文件。 (你似乎已经这样做了)
  4. 在需要时重新定义 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.