Visibility of Class members? - c++

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.

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.

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.
A private member's name is only accessible to other members and friends.
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...
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.

As a note: when you declare a class, the scope is private by default (opposed to a struct where members are public by default.)
The variable member 'x' is only accessible by your class and its friends. No one else can ever access 'x' directly (it can indirectly if you have a function returning a reference to it, which is a really bad idea.)
The text you quoted talks about visibility to the compiler, so X::x exists, no matter what. It won't disappear just because it's private. The visibility is used to find the member you are referencing and the first that matches is returned. At that point the compiler checks the accessibility, if accessible, you're all good. If not it is ill-formed.
Note that I mentioned friends. That keyword makes all variable members accessible. When the compiler deals with a friends, it completely ignores all the protected and private keywords.
In most cases, that's a very easy process. It goes in order. Period.
Where it becomes more complicated is when you start using virtual functions: these can be made public, protected, and private and that can change depending on the class declaration... (A derives from B and makes a protected virtual function public; it's generally not a good idea, but C++ doesn't prevent you from doing so.) Of course this only applies to functions, not variable members, so that's a different subject.

That accessability and visibility are independet confuses especially in such situations:
class A
{
public:
void Foo(int i){
}
};
class B : public A
{
private:
void Foo(){
}
};
int main(){
B b{};
b.Foo(12);
}
Programmers from other languages would expect that A::Foo(int) would be callable because it is public. The point here is, that the private B::Foo hides the inherited proc.
This can be solved with a using declaration using A::Foo. But it becomes really hard in this sitation:
class A
{
public:
void Foo(int i){
}
};
class B : public A
{
public:
using A::Foo;
private:
void Foo(){
}
};
class C : public B
{
public:
using B::Foo;
private:
void Foo(char c){
}
}
int main(){
B b{};
b.Foo(12);
}
Using requires that there is NO private function. AFAIK the best way to solve it is to use some prefixes / suffixes for private or protected functions (like do_XXX() or do_XXX_internal).
In the STL private members are usually prefixed by a single underscore (these are reserved identifiers).

Related

Why are private variables of a class accessible from an object in the class?

Let's say we have a class with a single private variable and a max method that takes a single parameter of the same type of the class:
class A
{
private:
int Number;
public:
A() : Number(0) {}
A(int val) : Number(val) {}
int max(A b)
{
if( Number > b.Number )
return Number;
return b.Number;
}
};
What is strange to me is that the parameter b in the max method has access to the private variable Number. However in the main function we do not have access to the parameter Number (as expected since it is declared private)
int main()
{
A a;
a.Number = 0; // ERROR
return 0;
}
So my question is why does the function in the class have access to the variable Number when it is declared private.
It's just the rule, that's all.
It's designed to make member functions, especially functions like assignment operators, copy constructors, and overloaded operators, simpler to write. If you couldn't access the members of the "other" object directly then you'd need a plethora of friend declarations or ugly "getters"; the latter tend to offer little more than a circumvention of encapsulation.
Perhaps the way you propose could have been the default, and to bring in the private and protected members and functions could have required the declaration
friend class;
But C++ was not designed this way, and that proposal would now be an hideous breaking change. Something to muse on though to recover your expected behaviour could be a declaration
friend class = delete;
which would, as far as I can tell, not be a breaking change. Why not propose something of this form to the ISO C++ Committee?
The principle idea behind encapsulation is to hide the internals of a class from external classes.
When you consider that the function you're writing is internal to the class A, it makes sense for the function to be aware of A's internals - regardless of the context.

Using declaration for overloaded inherited function with private accessibility

I have a class that looks something like this:
class A
{
public:
void foo(int arg) { foo(arg, false); }
private:
void foo(int arg, bool flag) {}
};
It is built this way because I want foo's flag argument to only be false when called from outside A. I want to inherit it privately, but allow calling foo:
class B : private A
{
public:
using A::foo;
};
However, this fails because the using declaraion attempts to bring all the overloads of foo into scope, including the private one, which the the compiler rightly rejects.
This isn't hard to fix, I can either:
Change the accessibility of A::foo(int, bool) to protected or public
Inherit A publicly; only public overloads of foo will be inherited
Change the name of A::foo(int, bool) so that the using declaration does not attempt to bring it into scope
This is a small, private project, and besides, that overload is only called inside A. So fixing the problem is a non-issue here. (I'm just going to rename the private overload.)
But it doesn't feel like it should be necessary. Why does the using declaration attempt to bring the non-accessible methods into scope? Is this particular case just not covered by the standard? Is there a way to fix this besides the methods I listed?
You can also redefine the overload you want and have it forward its argument to the function in A:
class B : private A
{
public:
void foo(int arg) { A::foo(arg); }
};
The using declaration is just too blunt a tool in this case. It brings function names into the derived class scope. And when the name refers to something private, it chokes. It can't distinguish overloads. The standard requires the names introduced by a using declaration to be accessible:
[namespace.udecl]/17
In a using-declarator that does not name a constructor, all members of
the set of introduced declarations shall be accessible. In a
using-declarator that names a constructor, no access check is
performed. In particular, if a derived class uses a using-declarator
to access a member of a base class, the member name shall be
accessible. If the name is that of an overloaded member function, then
all functions named shall be accessible. The base class members
mentioned by a using-declarator shall be visible in the scope of at
least one of the direct base classes of the class where the
using-declarator is specified.
The forwarding function can also be templated. So one won't need to redefine each function they want to expose individually.
class B : private A
{
public:
template<typename ...Args>
void foo(Args ...args) { A::foo(args...); }
};
It's "catch-all" like the using declaration, except the access specifier is checked only on template instantiation, i.e. when the function is called. So the template will be ill-formed based on its scope and whether or not the member in A is accessible there.
I found the following extract from Scott Meyer's Effective C++ which is related to your predicament (with emphasis added):
Item 33: Avoid hiding inherited names.
...
This means that if you inherit from a base class with overloaded functions
and you want to redefine or override only some of them, you need
to include a using declaration for each name you’d otherwise be hiding.
If you don’t, some of the names you’d like to inherit will be hidden.
...
It’s conceivable that you sometimes won’t want to inherit all the functions
from your base classes. Under public inheritance, this should
never be the case, because, again, it violates public inheritance’s is-a
relationship between base and derived classes. (That’s why the using
declarations above are in the public part of the derived class: names
that are public in a base class should also be public in a publicly
derived class.)
Under private inheritance, however, it can
make sense. For example, suppose Derived privately inherits from
Base, and the only version of the function that Derived wants to inherit is the
one taking no parameters. A using declaration won’t do the trick here,
because a using declaration makes all inherited functions with a given
name visible in the derived class.
No, this is a case for a different technique, namely, a simple forwarding function:
class Base {
public:
virtual void mf1() = 0;
virtual void mf1(int);
... // as before
};
class Derived: private Base {
public:
virtual void mf1() // forwarding function; implicitly
{
Base::mf1(); } // inline
};
}

The declaration of class in C++ combines the interface with the implementation of that interface?

I have a question about declaration of class.
I read the following lines in a paper: A C++ class declaration combines the external interface of an object with the implementation of that interface.
So, what is a external interface in C++? are there concept of interface in C++? how to understand this: A C++ class declaration combines the external interface of an object with the implementation of that interface. ?
I think it's referring to the API — i.e. the signatures of the public functions — as contrasted to the implementation — i.e. private functions and data members.
class T
{
// Here are some private things.
// You might say that these are part of
// the class's implementation.
int x;
int y;
void foo();
void bar();
public:
// And here are some public things, that
// constitute the class's API or "interface",
// which is the mechanism by which you may
// interact with objects of this type.
void baz();
void boz();
};
Notice how they are all present, right there, in the single class definition, and they must be. "Combined".
Ultimately, though, you'd have to ask the author of the paper as the terminology level used is up to them. Conceivably they could be talking about inheritance heirarchies and abstract base classes... though I can't find a way to rationalise the assertion that C++ class definitions "combine" those in any real sense.
I think the definition by the paper is a bit inaccurate. The terms declaration, implementation, definition, and interface should be used with some rigor. I will try to explain a little bit.
First of all, a class declaration does not specify any interface: it simply states that the class exists. For instance, these are some declarations:
class my_class;
struct my_structure;
template<typename T> class X;
A class definition on the other hand declares which are the members of a class (functions and data). Without entering too much into details, the term external interface in the sense used by the paper you quote roughly means "a specification of what can be done with objects of that class by code which belongs to functions that are not members of that class".
Here is an example of a class definition:
class my_class
{
public:
void foo();
int bar(int x) const;
private:
void do_something();
int data;
};
The term external interface used in the paper you mention almost certainly refers to the public interface, which is the list of all members of the class which have public visibility. All member variables and functions of a class can have one of three levels of visibility: public, protected, or private. I am not delving into details here, but it should be enough to say that public members (data or functions) are those members that can be accessed from functions which are not themselves members of the class, while private members can only be accessed from functions which are members of the class. The protected qualifier is related with inheritance and I don't think that needs to be covered to answer your question.
Now the public interface of class my_class above declares functions foo() and bar(), but does not yet specify their implementation or, in more formal terms, their definition. In general, member functions are not necessarily defined in a class definition (you can't tell what foo() does just by looking at the definition of my_class, can you?). Thus, unless you write the body of a member function directly after its declaration, a separate member function definition is necessary to specify the implementation of that function:
void my_class::foo()
{
std::cout << "hello, i'm foo" << std::endl;
}
int my_class::bar(int x)
{
do_something();
x * 2 + 1;
}
void my_class::do_something()
{
std::cout << "doing something..." << std::endl;
}
Due to the different visibility levels of these functions, a client code from a function external to class my_class can call functions foo() and bar(), because they belong to the public interface, but not function do_something(), which is declared as private. For instance:
int main()
{
my_class c;
c.foo(); // OK!
c.do_something(); // ERROR!
}
The rationale behind the fact that some functions can be made accessible from the outside of a class and other cannot is to be found in a good design principle that goes under the name of "information hiding". By exposing to your clients only a set of services and hiding the way those services are actually implemented (e.g. function bar() invokes the private function do_something()), you create a layer of abstraction that protects client code from possible internal changes in the implementation of those services.
So finally, I believe that what the writer of the sentence "A C++ class declaration combines the external interface of an object with the implementation of that interface" actually wants to say is that from the definition of a class you can get a hint on what are the services that class exposes to its clients ("external interface", i.e. public functions) and what are the functions and variables that are used internally to realize those services ("implementation", i.e. private functions and member variables).
I apologize if it took a bit long to finally give you the interpretation of that sentence, but I felt like some clarification was in order. Anyway, this was necessarily just a short summary of this articulated topic: I am sure you can find better sources if you google all these terms or if you buy a good book on C++.
P.S.: Also please keep in mind, that formally the term (and keyword!) interface means something very specific in C++, which requires introducing the notion of pure virtual function. I thought it was not the case of explaining that, as it was likely unrelated with the intended meaning of the word "interface" in the sentence you quoted.
You could view the public members of a class as an external interface.
There is no interface in C++ as you have it in Java, for example. You can only define a base class and define some virtual member functions, which must be implemented by derived classes.
A class declaration includes public, protected and/or private members. The protected and private members could be seen as "implementation" details, but not necessarily as implementation of that public interface.
The interface contains declaration of the method, and this is found in header files. This header files is correlated with some source files where appear the code for this methods. fr example, you can see how can be add a class in Eclipse CDT.

Where would you use a friend function vs. a static member function?

We make a non-member function a friend of a class when we want it to access that class's private members. This gives it the same access rights as a static member function would have. Both alternatives would give you a function that is not associated with any instance of that class.
When must we use a friend function? When must we use a static function? If both are viable options to solve a problem, how do we weigh up their suitability? Is there one that should be preferred by default?
For example, when implementing a factory that creates instances of class foo which only has a private constructor, should that factory function be a static member of foo (you would call foo::create()) or should it be a friend function (you would call create_foo())?
Section 11.5 "The C++ Programming Language" by Bjarne Stroustrup states that ordinary member functions get 3 things:
access to internals of class
are in the scope of the class
must be invoked on an instance
friends get only 1.
static functions get 1 and 2.
The question seems to address the situation where the programmer needs to introduce a function that does not work on any instance of a class (hence the possibility of choosing a static member function). Therefore, I will limit this answer to the following design situation, where the choice is between a static function f() and a friend free function f():
struct A
{
static void f(); // Better this...
private:
friend void f(); // ...or this?
static int x;
};
int A::x = 0;
void A::f() // Defines static function
{
cout << x;
}
void f() // Defines friend free function
{
cout << A::x;
}
int main()
{
A::f(); // Invokes static function
f(); // Invokes friend free function
}
Without knowing anything in advance about the semantics of f() and A (I'll come back to this later), this limited scenario has an easy answer: the static function is preferable. I see two reasons for this.
GENERIC ALGORITHMS:
The main reason is that a template such as the following can be written:
template<typename T> void g() { T::f(); }
If we had two or more classes that have a static function f() on their interface, this would allow us writing one single function that invokes f() generically on any such class.
There is no way to write an equivalent generic function if we make f() a free, non-member function. Although it is true that we could put f() into a namespace, so that the N::f() syntax could be used to mimic the A::f() syntax, it would still be impossible to write a template function such as g<>() above, because namespace names are not valid template arguments.
REDUNDANT DECLARATIONS:
The second reason is that if we were to put the free function f() in a namespace, we would not be allowed to inline its definition directly in the class definition without introducing any other declaration for f():
struct A
{
static void f() { cout << x; } // OK
private:
friend void N::f() { cout << x; } // ERROR
static int x;
};
In order to fix the above, we would to preceed the definition of class A with the following declaration:
namespace N
{
void f(); // Declaration of f() inside namespace N
}
struct A
{
...
private:
friend void N::f() { cout << x; } // OK
...
};
This, however, defeats our intention of having f() declared and defined in just one place.
Moreover, if we wanted to declare and define f() separately while keeping f() in a namespace, we would still have to introduce a declaration for f() before the class definition for A: failing to do so would cause the compiler to complain about the fact that f() had to be declared inside namespace N before the name N::f could be used legally.
Thus, we would now have f() mentioned in three separate places rather than just two (declaration and definition):
The declaration inside namespace N before A's definition;
The friend declaration inside A's definition;
The definition of f() inside namespace N.
The reason why the declaration and definition of f() inside N cannot be joined (in general) is that f() is supposed to access the internals of A and, therefore, A's definition must be seen when f() is defined. Yet, as previously said, f()'s declaration inside N must be seen before the corresponding friend declaration inside of A is made. This effectively forces us to split the declaration and the definition of f().
SEMANTIC CONSIDERATIONS:
While the above two points are universally valid, there are reasons why one might prefer declaring f() as static over making it a friend of A or vice versa which are driven by the universe of discourse.
To clarify, it is important to stress the fact that a member function of a class, whether it is static or non-static, is logically part of that class. It contributes to its definition and thus provides a conceptual characterization of it.
On the other hand, a friend function, in spite of being granted access to the internal members of the class it is friend of, is still an algorithm which is logically external to the definition of the class.
A function can be friend of more than one class, but it can be member of just one.
Thus, in a particular application domain, the designer may want to keep into consideration the semantics of both the function and the class when deciding whether to make the former a friend or a member of the latter (this applies not only to static functions, but to non-static functions as well, where other language constraints may intervene).
Does the function logically contribute to characterize a class and/or its behavior, or is it rather an external algorithm? This question can't be answered without knowledge of the particular application domain.
TASTE:
I believe that any argument other the ones just given stems purely from a matter of taste: both the free friend and the static member approach, in fact, allow to clearly state what the interface of a class is into one single spot (the class's definition), so design-wise they are equivalent (modulo the above observations, of course).
The remaining differences are stylistic: whether we want to write the static keyword or the friend keyword when declaring a function, and whether we want to write the A:: class scope qualifier when defining the class rather than the N:: namespace scope qualifier. Thus, I will not comment further on this.
The difference is clearly expressing the intent of the relationship between the class and the function.
You use friend when you want to intentionally indicate a strong coupling and special relationship between two unrelated classes or between a class and a function.
You use static member function when the function is logically a part of the class to which it is a member.
Friend functions (and classes) can access the private and protected members of your class.
There's rarely a good case for using a friend function or class. Avoid them in general.
Static functions may only access static data (that is, class-scoped data). They may be called without creating an instance of your class. Static functions are great for circumstances you want all of the instances of your class to behave the same way. You can use them:
as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without instantiating the class.
Friend functions are functions which are not in the class and you want to give them access to private members of your class.
And this(static vs. friend) is not a matter of using one vs the other since they are not opposites.
The standard requires that operator = () [] and -> must be members, and class-specific
operators new, new[], delete and delete[] must be static members. If the situation
arises where we don't need the object of the class to invoke a function, then make
the function static. For all other functions:
if a function requires the operators = () [] and -> for stream I/O,
or if it needs type conversions on its leftmost argument,
or if it can be implemented using the class' public interface alone,
make it nonmember ( and friend if needed in the first two cases)
if it needs to behave virtually,
add a virtual member function to provide the virtual behaviour
and implement in terms of that
else
make it a member.
Static function can only access members of one class. Friend function has access to several classes, as explained by the following code:
class B;
class A { int a; friend void f(A &a, B &b); };
class B { int b; friend void f(A &a, B &b); };
void f(A &a, B &b) { std::cout << a.a << b.b; }
f() can access data of both A and B class.
One reason to prefer a friend over static member is when the function needs to be written in assembly (or some other language).
For instance, we can always have an extern "C" friend function declared in our .cpp file
class Thread;
extern "C" int ContextSwitch(Thread & a, Thread & b);
class Thread
{
public:
friend int ContextSwitch(Thread & a, Thread & b);
static int StContextSwitch(Thread & a, Thread & b);
};
And later defined in assembly:
.global ContextSwitch
ContextSwitch: // ...
retq
Technically speaking, we could use a static member function to do this, but defining it in assembly won't be easy due to name mangling (http://en.wikipedia.org/wiki/Name_mangling)
Another situation is when you need to overload operators. Overloading operators can be done only through friends or non-static members. If the first argument of the operator is not an instance of the same class, then non-static member would also not work; friend would be the only option:
class Matrix
{
friend Matrix operator * (double scaleFactor, Matrix & m);
// We can't use static member or non-static member to do this
};
A static function is a function that does not have access to this.
A friend function is a function that can access private members of the class.
You would use a static function if the function has no need to read or modify the state of a specific instance of the class (meaning you don't need to modify the object in memory), or if you need to use a function pointer to a member function of a class. In this second instance, if you need to modify the state of the resident object, you would need to pass this in and use the local copy. In the first instance, such a situation may happen where the logic to perform a certain task is not reliant on an object's state, yet your logical grouping and encapsulation would have it be a member of a specific class.
You use a friend function or class when you have created code that is not a member of your class and should not be a member of your class, yet has a legitimate purpose for circumventing the private/protected encapsulation mechanisms. One purpose of this may be that you have two classes that have need of some common data yet to code the logic twice would be bad. Really, I have only used this functionality in maybe 1% of the classes I've ever coded. It is rarely needed.
A friend function can not be inherited while a static function can be. So when an aim can be achieved with both static function and friend function, think that whether you want to inherit it or not.
Static function can be used in many different ways.
For example as simple factory function:
class Abstract {
private:
// no explicit construction allowed
Abstract();
~Abstract();
public:
static Abstract* Construct() { return new Abstract; }
static void Destroy(Abstract* a) { delete a; }
};
...
A* a_instance = A::Conctruct();
...
A::Destroy(a_instance);
This is very simplified example but I hope it explains what I meant.
Or as thread function working with Your class:
class A {
public:
static void worker(void* p) {
A* a = dynamic_cast<A*>(p);
do something wit a;
}
}
A a_instance;
pthread_start(&thread_id, &A::worker, &a_instance);
....
Friend is completely different story and they usage is exactly as described by thebretness
Friend functions can access the private and protected members of other classes.
Means they can be used to access all the data weather it is private or public.
So friend functions are used to access that data which static methods can not.
Those methods are made static which are called so many times that declaring a different location inside every object, for them becomes too costly(In terms of memory).
This can be made clear with the help of example:
Let the class's name is fact and its data member is n(which represents integer whose factorial is concern)
then in this case declaring find_factorial() as static would be wise decision!!
They are used as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Now we are clear with following questions..
When a friend function is used? When a static function is used?
Now If both are viable options to solve a problem,
We can weight up their suitability in terms of accessibility(accessibility of Private data) and memory efficiency.
By default no one can be preferred as there are many situation when we need better memory management and sometimes we are are concerned with the scope of data.
For example:
foo::create() will be preferred over create_foo() when we have to call create() method after every small instance of time and we are not interested on scope of data(Private data)
And if we are interested to get the private information of more than one class(s) then create_foo() will be preferred over foo::create().
I hope this would help you!!
Here is what I think it is:
Friend function- when you need access to a different class member, but the classes are not related. Static function- when you no not need access to the 'this' pointer. But, I have a feeling there is more to it....
Static data members always share the memory.
only static function can used static data members.
static member function can be called with class name.
They must be defined outside of the class when we create a object of static member or member function in the class. It will automatically initialize the value.
It always used keyword static.
Static members can share by all the objects.
Type and scope of data members and member function is outside of the class.
A static member variable must be defined outside of the class.

c++ using declaration, scope and access control

Typically the 'using' declaration is used to bring into scope some member functions of base classes that would otherwise be hidden. From that point of view it is only a mechanism for making accessible information more convenient to use.
However: the 'using' declaration can also be used to change access constraints (not only for functions but also for attributes). For example:
class C{
public:
int a;
void g(){ cout << "C:g()\n"; }
C() : a(0){}
};
class D : public C{
private:
using C::a;
using C::g;
public:
D() { a = 1; }
};
int main(void){
D d;
cout << d.a << endl; //error: a is inaccessible
C *cp = &d;
cout << cp->a << endl; //works
d.g(); //error: g is inaccessible
cp->g(); //works
return 0;
}
I think this limitation of access in the derived class is actually of no use, because you can always access g() and a from a pointer to the base class. So should't there be at least some kind of compiler warning? Or wouldn't it been even better to forbid such limitation of access by a derived class? The using declaration is not the only possibility to add constraints to access. It could also be done via overriding a base class' function an placing it in a section with more access constraints.
Are there some reasonable examples where it is indeed nessecary to limit access in such a way? If not I don't see why it should be allowed.
And another thing: at least with g++ the same code compiles well without the word 'using'. That means for the example above: it's possible to write C::a; and C::g; instead of using C::a; using C::g; Is the first only a shortcut for the latter or are there some subtle differences?
//EDIT:
so from the discussion and answers below my conclusion would be:
- it's allowed to limit access constraints in derived classes with public inheritance
- there are useful examples where it could be used
- it's use might cause problem in combination with templates (e.g. a derived class could not be a valid parameter for some template class/function any more although it's base is)
- a cleaner language design should not allow such use
- compiler could at least issue some kind of warning
With regard to your declaration without using: These are called "access declarations", and are deprecated. Here is the text from the Standard, from 11.3/1:
The access of a member of a base class can be changed in the derived class by mentioning its qualified-id in
the derived class declaration. Such mention is called an access declaration. The effect of an access declaration qualified-id; is defined to be equivalent to the declaration usingqualified-id; [Footnote: Access declarations are deprecated; member using-declarations (7.3.3) provide a better means of doing the same things. In earlier versions of the C++ language, access declarations were more limited; they were generalized and made equivalent to using-declarations - end footnote]
I would say that most often it's not good to change public members to private or protected members in the derived class, because this will violate the substitution principle: You know a base class has some functions, and if you cast to a derived class then you expect those functions to be callable too, because the derived class is-a base. And like you already mentioned, this invariant is already enforced anyway by the language allowing to convert (which working implicitly!) to a base class reference, or qualifying the function name, and then calling the (then public) function.
If you want to forbid someone calling a set of functions of the base, then i think this hints that containment (or in rare cases, private inheritance) is a better idea.
While the using declaration you showed does provide a mechanism to change access level (but only down), that is not the primary use of it in such a context. A using context there is primarily intended to allow access to functions that would otherwise be shadowed from the base class due to the language mechanics. E.g.
class A {
public:
void A();
void B();
};
class B {
public:
using A::B;
void B(int); //This would shadow A::B if not for a using declaration
};
The declaration
using C::a
brings "a" to the local naming scope so that you can later use "a" to refere to "C::a"; since that, "C::a" and "a" are interchangeable as long as you don't declare a local variable with name "a".
The declaration does not change access rights; you can access "a" in the subclass only because "a" is not private.