Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare main() as friend function in C++

Tags:

c++

I have a class that I only wish clients create them one object per process. Instead of singleton, a better way (I believe) is to tell the clients to only create them in main(). So a natural enforcement is to make the constructor private and main() as a friend.

It works this way:

class A { friend int main(int, char**); A() {} };
int main(int, char **) { A a; }

But it breaks when I need to put class A in a namespace:

namepace ns { class A { friend int main(int, char**); A() {} }; }
int main(int, char **) { ns::A a; }

The problem is scoping: the compiler now thinks

friend int main 

means a function named main() in namespace ns. So the real main() becomes irrelevant.

So the question is: how to fix this? Of course I'll have to put class A in a namespace.

like image 231
Ralph Zhang Avatar asked Jan 29 '13 12:01

Ralph Zhang


People also ask

Can we declare main function as a friend function?

main() can very well be a friend of any class. Just declare it as a friend inside the class like you do for other member functions.

Where we should declare a function as a friend to a?

By declaring a function as a friend, all the access permissions are given to the function. The keyword “friend” is placed only in the function declaration of the friend function and not in the function definition. When friend function is called neither name of object nor dot operator is used.

Can we declare friend function in private?

A friend function can be declared in the private or public part of a class without changing its meaning. Friend functions are not called using objects of the class because they are not within the class's scope. Without the help of any object, the friend function can be invoked like a normal member function.


2 Answers

You need to declare main in the global namespace before the class definition, since friend declarations can only introduce names in the surrounding namespace:

int main(int, char**);

and qualify the name when referring to it inside the namespace:

namepace ns { class A { friend int ::main(int, char**); A() {} }; }
//                                 ^^
like image 149
Mike Seymour Avatar answered Oct 05 '22 09:10

Mike Seymour


Use "::" to qualify something as being in the global namespace, i.e.:

friend int ::main(int argc, char** argv);
like image 32
sheu Avatar answered Oct 05 '22 09:10

sheu