views:

39

answers:

5

In Java they have package access specifier which enables the function to be used only by classes from this same "package" (namespace) and I see good things about it. Especially when design of models are in play. Do you think that something like this could be useful in C++?
Thanks.

A: 

In C++, if you need this, then use classes.

IMO, Access rules are complicated enough as they are.

(Note that you can have classes which contain nothing but static member functions, effectively implementing what you want.)

sbi
@sbi I don't think that with static fnc you could achieve this. Say you have class A with only static members. You can still access those members from outside the namespace this class is declared in. And I do not understand how can you achieve this by using classes? Can you elaborate on this?
There is nothing we can do
@A-ha just change the visibility of the static function to private, then attempt to use it outside of the class -- you'll see how this is an effective means to keep clients from using private implementations. the compiler will reject the program.
Justin
@Justin yes but it will also restrict other classes from using those functions and the whole point is to make them available only to classes in this same namespace. So in effect they can interact with this class but only if they are in the same namespace in which this class is.
There is nothing we can do
@A-ha: Use the `class` as a `namespace`. (Of course, the drawback of this is that namespaces are open, while classes are not.)
sbi
A: 

A Java package is roughly:

  • A way of grouping source files
  • Creating compressed binaries

In C++, the first can be achieved via judicious usage of namespace. There is no way to emulate the latter using a language construct though.

dirkgently
A: 

Yes, this can be accomplished. You may restrict visibility by public, protected, private keywords, as well as source visibility.

Declared visibility is commonly understood.

Source visibility (if you're coming from Java) is a bit different.

Java: you have one file for an object interface/implementation. Cpp: you have one file for an interface. the implementation may lie in the interface, or one or more implementation (cpp, cxx) files.

If you use abstract classes/interfaces/functions apart from the public interface of the library, they are effectively hidden and not accessible (well, this is false if you have particularly nosy users who dump symbols -- then they may redeclare the interface, and link to the symbols but... that's obviously undefined territory for them). So you only need to make the symbols you like visible. It's a good idea to use a package/library naming convention to avoid linking errors - place the classes in a namespace reserved for the library's private implementation. Simple.

Would it be useful in C++... it's not bad, although I personally think there are higher priorities for the language.

example of source visibility:

/* publicly visible header file */

namespace MON {
class t_button {
protected:
    t_button();
    virtual ~t_button();
public:
    typedef enum { Default = 0, Glowing = 1 } ButtonType;
    /* ... all public virtual methods for this family of buttons - aka the public interface ... */
public:
    t_button* CreateButtonOfType(const ButtonType& type);
};
}

/* implementation file -- not visible to clients */

namespace MON {
namespace Private {
class t_glowing_button : public t_button {
public:
    t_glowing_button();
    virtual ~t_glowing_button();
public:
    /* ... impl ... */
};
}
}

MON::t_button* MON::t_button::CreateButtonOfType(const ButtonType& type) {
    switch (type) {
        case Glowing :
            return new Private::t_glowing_button();

        case Default :
            return new Private::t_glowing_button();

            /* .... */
        default :
            break;
    }

    /* ... */
    return 0;
}
Justin
@Justin but if you put those functions that in effect they are not in a interface they cannot be used by other classes from this same namespace could they? If you could give an example it would be great.
There is nothing we can do
if the glowing button (in the newly added example) is visible to other classes/interfaces, then it may be used. how you organize the library may be very important (or not at all), depending how much you'd like to abstract. fwiw, c++ also provides `friend's. so... cpp has *most* of the functionality of Java in this regard (visibility) - that's probably why a package visibility feature is not a high priority for me, personally.
Justin
A: 

you could provide a header file which should be "public" for users of the "package". The stuff that should be used internally only can have their header files in a folder called "internal" or (package name). This does not prevent someone to actually include those files, but you communicate that he should not!

Philipp
A: 

As others have pointed out the usual way to do this is just by convention however C++ does provide friends which would allow you to specify that only the classes/functions you specify can access internals of a class e.g. private functions, this can be used to provide package like restrictions.

Mostly friends are avoided in C++ as they tend to increase coupling

There isn't really a direct equivalent because C++ isn't e.g. designed to cope with mobile code, :. access specifiers are a conveneince not a security feature anyway.

jk