问题
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 whole story is that this is a library the contains a class in one file and the main in another file, all linked into my library. The library is providing the basis for a Process Framework, which is why the main is in the library and not the process.
Below is a stripped down version of what I have.
pf.hpp
using namespace std;
namespace MyNamespace
{
class ProcessManager
{
public:
friend int main(int argc, char** argv);
private:
void test();
};
};
pf.cpp
#include "pf.h"
namespace MyNamespace
{
ProcessManager::test()
{
cout << "My friend has accessed my member" << endl;
}
};
pfmain.cpp
#include "pf.hpp"
int main(int argc, char** argv)
{
ProcessManager pm;
pm.test();
}
Note that this fails on the compilation of the library
What I have tried is:
- Moving the friend all over the place
- Making the friend reference to main use global scope (e.g. ::main)
- Making friend and main declarations use global scope
What am I missing?
Thanks!
回答1:
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();
};
};
回答2:
@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.
回答3:
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.
回答4:
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();
来源:https://stackoverflow.com/questions/8619356/how-do-i-make-main-a-friend-of-my-class-from-within-a-library