How do I make main a friend of my class from within a library?

后端 未结 4 820
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-12 03:03

Please see my first attempt at answering this . I neglected to tell the whole story before in an attempt to simplify things. Turns out my example works! Sorry.

The w

相关标签:
4条回答
  • 2021-01-12 03:07

    @parapura provided a solution, but doesn't explain why you first have to declare main in the global scope.

    §7.3.1.2 [namespace.memdef] p3

    [...] If a friend declaration in a nonlocal class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. [...]

    So with that in mind, your code would look somewhat like this:

    namespace MyNamespace
    { // MyNamespace is the innermost enclosing namespace
      // 'main' from the friend declaration is treated
      // as if it was a member of 'MyNamespace'
      int main(int argc, char** argv);
    
      class ProcessManager
      {
      public:
        friend int main(int argc, char** argv);
      private:
        void test();
      };
    };
    

    Now it should be clear why the global main function wasn't your friend.

    0 讨论(0)
  • 2021-01-12 03:08

    I don't think you actually want to do what you are doing. This really seems like a hack and a design problem. If you really want to expose the internals of your class in some specialized circumstance, you could make an accessor class which is also defined inside your library.

    Something like this might work (may need appropriate forward declarations, etc. -- this is just a starting point):

    class ProcessManagerAccessor
    {
    public:
        ProcessManagerAccessor(ProcessManager & pm) : pm_(pm) { }
    
        // add public methods to expose internals
        void test() { pm_.test(); }
    
    private:
        ProcessManager & pm_;
    };
    
    class ProcessManager
    {
    public:
        friend class ProcessManagerAccessor;
    
        // ...
    };
    
    // ...
    
    ProcessManager pm;
    ProcessManagerAccessor pma(pm);
    pma.test();
    
    0 讨论(0)
  • 2021-01-12 03:13

    Just declare the main outside the MyNamespace and specify global namespace :: in friend statement

    //in header file of ProcessManager
    //your pf.h
    
    int main(int argc, char** argv);
    
    namespace MyNamespace
    {
      class ProcessManager
      {
      public:
        friend int ::main(int argc, char** argv);
      private:
        void test();
      };
    };
    
    0 讨论(0)
  • 2021-01-12 03:14

    A common answer might be to provide an "application" singleton class, like e.g. QApplication in Qt, an reduce your main to something like

    int main (int argc, char** argv) {
        YourApplication app (argc, argv);
        return app.execute();
    }
    

    Then you reduce your friendness concern to class YourApplication vs your other classes, and you know how to do that.

    0 讨论(0)
提交回复
热议问题