Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visibility of Class members?

I think i'm aware of accessibilty but I'm not sure if I understand visibility very clearly

For example:

class X
{
   int x;
};

Here, 'x' is only visible in class and but accessible outside of class. If I'm correct, Can someone explain the text in that answer about how visibility is not controlled etc..?

(C++03/11.0) It should be noted that it is access to members and base classes that is controlled, not their visibility. Names of members are still visible, and implicit conversions to base classes are still considered, when those members and base classes are inaccessible. The interpretation of a given construct is established without regard to access control. If the interpretation established makes use of inaccessible member names or base classes, the construct is ill-formed.

like image 305
user1086635 Avatar asked Jan 01 '12 23:01

user1086635


2 Answers

Perhaps this example helps:

class Bob
{
private:
    int foo(int, int);
};

class David : Bob
{
    void goo() {
        int a = foo(1, 2);  // #1
    }
};

class Dani : Bob
{
     void foo();
     void goo() {
         int a = foo(1, 2); // #2
     }   
};

On line #1, the name foo is visible, but the function which it names is not accessible (on account of being private to Bob). This is a compilation error, but the compiler knows that there is a potential function Bob::foo that would match, but isn't accessible.

On line #2, the name foo only refers to Dani::foo, while Bob::foo is not visible (because it is hidden), and so there is simply no matching function for the call foo(1, 2). This is also a compilation error, but this time the error is that there is no matching function at all for the call.

like image 89
Kerrek SB Avatar answered Oct 19 '22 15:10

Kerrek SB


C++ has some esoteric feature concerning private class member names visibility and accessibility. By definition, a private class member name is only accessible by the class members and friends. However the rule of visibility can confuse many. They can be summarized as follows.

  1. A private member's name is only accessible to other members and friends.
  2. A private member is visible to all code that sees the class's definition. This means that its parameter types must be declared even if they can never be needed in this translation unit...
  3. Overload resolution happens before accessibility checking.

In C++ today ("C++03" and earlier variants), the notions of accessibility and visibility are independent. Members of classes and namespaces are visible whenever they are "in scope" and there is no mechanism to reduce this visibility from the point of declaration. Accessibility is only a parameter for class members and is orthogonal to the notion of visibility. This latter observation is frequently surprising to novice C++ programmers. See this PDF.

Consider the following example.

#include < complex>

class Calc 
{ 
    public: 
        double Twice( double d ); 
    private: 
        int Twice( int i ); 
        std::complex Twice( std::complex c ); 
};

int main() 
{ 
    Calc c; 
    return c.Twice( 21 ); // error, Twice is inaccessible 
}    

When the compiler has to resolve the call to a function, it does three main things, in order:

  • Before doing anything else, the compiler searches for a scope that has at least one entity named Twice and makes a list of candidates. In this case, name lookup first looks in the scope of Calc to see if there is at least one function named Twice; if there isn't, base classes and enclosing namespaces will be considered in turn, one at a time, until a scope having at least one candidate is found. In this case, though, the very first scope the compiler looks in already has an entity named Twice — in fact, it has three of them, and so that trio becomes the set of candidates. (For more information about name lookup in C++, with discussion about how it affects the way you should package your classes and their interfaces

  • Next, the compiler performs overload resolution to pick the unique best match out of the list of candidates. In this case, the argument is 21, which is an int, and the available overloads take a double, an int, and a complex. Clearly the int parameter is the best match for the int argument (it's an exact match and no conversions are required), and so Twice(int) is selected.

  • Finally, the compiler performs accessibility checking to determine whether the selected function can be called.

Note that accessibility (defined by modifiers in C++) and visibility are independent. Visibility is based on the scoping rules of C++. A class member can be visible and inaccessible at the same time.

Static members as an example are visible globally through out the running of your application but accessible only with regard to the modifier applied to them.

like image 22
Lion Avatar answered Oct 19 '22 14:10

Lion