Home > Enterprise >  Cyclic Reference issue with includes for friend class
Cyclic Reference issue with includes for friend class

Time:11-13

I have 2 classes: S and R. R has an intance of type S. I want to have R as friend class to have acces to S private methods. Unfortunately I couldn't build it. Please help me how can I solve this. I tried forward declaration in more ways but it didn't work. I get the following error

R.hpp:12:15: error: ‘n1::n2’ has not been declared
  12 |         R(n1::n2::Sptr s);

Thanks a lot in advance!.

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;
}

 

CodePudding user response:

You can get the program to work(compile) by using the following modifications in your files:

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();
    }
  }
}

The output of the above program can be seen here.

CodePudding user response:

  1. Remove all cross header file includes. (you appear to have done this)
  2. Replace missing symbols with forward declarations in the header.
  3. Add header file includes removed into cpp files. (you appear to have done this)
  4. Redefine the shared_ptr alias when you need it.
  • Related