views:

85

answers:

4

As far as i know, there're only 3 access-specifiers in C++: private, public, protected

With these 3 access-specifiers, how can i make a method usable to the classes in the project but unusable to the "foreigners" ??(like internal and public in C#)

+8  A: 

C++ does not know what a project is.

C++ knows about classes, where it offers the three access specifiers you mentioned.

C++ knows about translation units, where it offers two access specifiers: internal and external linkage.

Edit: About internal and external linkage, this is related to whether a symbol will be seen outside of the translation unit (the object file). Any global static or const variable defined in the TU has internal linkage. Others have external linkage.

Didier Trosset
1+ - nice answer, but maybe you should elaborate a bit on the linkage bit
jalf
+1 From there you can plan several ways to isolate your code. Now, it would be nice if they add Modules in TR2 (or C++2015) that would allow to specify what is visible from outside without having to split classes using (for example) PIMPL idiom.
Klaim
I'm also curious about how "linkage" makes things better
rhapsodyn
Items with internal linkage cannot be called by name from outside the translation unit. A "foreigner" would have to sift through the code, find the address, and call it through a function pointer. In case of inlining the function might not even exist as code that can be called separately.
Ben Voigt
+3  A: 

Put simply, you don't. C++ is not anything like C#.

If you don't want to make a class available outside a given library or executable, then simply don't provide the header file to users of your project.

greyfade
Especially note: C++ access modifiers are for organizational purposes and having the compiler help you write more maintainable code. They are not for security or protecting intellectual property.
Ben Voigt
+1  A: 

You can use the passkey friend idiom.

This isn't a term you'll be able to search for, though. The idea isn't new, though not terribly common, and sort of arose on SO. The link above is my attempt at a generic solution (impossible to do cleanly in C++03, beautiful in C++0x).

I'm sure there are other ways to try to do it, but for some reason I have an attachment to the above...:)


But otherwise, no. A far more common and simpler solution is to just throw your stuff in a detail namespace (common throughout Boost, for example), and say "don't go there".

GMan
A: 

The two closest things that you have to a solution are

  1. Have an internal namespace that you use in your code which you don't really publicize. Users of your library then use whatever namespace that you use that is intended for public consumption. However, it's not enforced. It's just obfuscated in that they won't necessarily know about the namespace or are told not to use it, so they don't.

  2. Use friend. This is enforced by the compiler. If a class is a friend of another class, or if a function is a friend of a class, then it can access its private member functions while others can't. Unfortunately, that means that the friend has access to all private members, so it can give more access to various classes or functions than you'd like (though it would be within your own classes and functions rather than that of the users of your library).

C++ is older than such languages as C#, Java, and D which give you finer grained control over access levels. C++ pioneered a lot of this sort of stuff, and it didn't always get it right. Designers of newer languages have learned from it and improved upon it in many ways, so you're going to find certain concepts in newer languages which C++ just doesn't have (though sometimes C++ has concepts that newer languages didn't adopt). Other example would be packages and sealed/final classes and functions.

Jonathan M Davis