Hide class members outside namespace - c++

I have a collection of classes that have node like relationships. Due to this, I need to access some of the parents/chilren functions that I'd otherwise like to keep away from the end user since they just clutter the suggested method list, make no sense and break things really bad when used from outside their own "ecosystem".
I figured if they'd all inherit the same base class with virtual placeholder functions then I could access the protected members but apparently not. Is there a way to hide class members from access outside a certain namespace or a container class while being accessible from within?

If you really have to has access to some protected/private data you can make friend classes.
From Wikipedia:
class B {
friend class A; // A is a friend of B
private:
int i;
};
class A {
public:
A(B& b) {
b.i = 0; // legal access due to friendship
}
};

Related

Accessing base class elements without breaking encapsulation

I have created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.

Accessing private C++ methods within C++/CLI wrapper

Given a class method in C++ that has to be private there, how to make C++/CLI access it. Example: C++ class has a private constructor that shouldn't be exposed to the external user, C++/CLI managed code has to have similar private constructor, but internally it must access private C++ constructor to instantiate a member pointer referring to C++ native class.
Keep in mind, first of all, the goal of making things inaccessible (i.e. private) generally contradicts the goal of making things accessible. If you're able to change the class declaration, then you have some options. I don't know the specifics of your C++/CLI requirements, but perhaps one of these options will give you what you need.
Protected and Inheritance
To an "outsider", private and protected members are equally inaccessible. But to a subclass, private is still private while protected members are accessible. You can gain access to protected members by subclassing. This can be one way to unit test "private" members of a class without fully exposing it to the world.
class A {
protected: // was private
int sum(int a, int b);
};
class TestA : public A {
public:
bool testSum(int expected, int a, int b) {
return expected == sum(a, b);
}
};
So access to protected method sum in class A becomes accessible by making it protected and subclassing. The private member will remain inaccessible to everything else except subclasses.
Static Factory Method
You mentioned a private constructor; if you are needing to manage construction, you might accomplish that with a static factory method. For instance:
class Foobar {
private:
Foobar() { } // Don't let anyone just make one.
public:
static Foobar* Create() { return new Foobar; }
};
// To create a Foobar instance:
Foobar* pfoo = Foobar::Create();
This is not the best interface (better to use a shared_ptr, for instance), but it demonstrates my meaning. Note that since the factory function Create is public, anyone can create one. However, you can change the body of Create to something more complex: include bookkeeping, initialization, etc. The factory method is a way to manage creation, not restrict it. Granted, you may not want this, but it's an option if you need to manage construction.
Friends
C++ permits giving access of the private parts of classes to other classes/functions via the friend keyword.
class A {
int x; //private
friend class B;
};
class B {
void foobar(A& a) {
a.x = 42; // permissible, because A declared class B a friend
}
};
Friendship can be granted to another class or to a function. This can easily break encapsulation and make code difficult to follow or keep safe, but it also gives you the means to expose private members to exactly just those who need it.

access private members in inheritance

I have a class A, which have a field val declared as private.
I want to declare a class B, that inherit from A and have an access to val.
Is there a way to do it on C++?
I want to do it because I need to overload some functions of A, without changing A code at all.
Thanks.
Quick answer: You don't. Thats what the protected key-word is for, which you want to use if you want to grant access to subclasses but no-one else.
private means that no-one has access to those variables, not even subclasses.
If you cannot change code in A at all, maybe there is a public/protected access method for that variable. Otherwise these variables are not meant to be accessed from subclasses and only hacks can help (which I don't encourage!).
Private members of a base class can only be accessed by base member functions (not derived classes). So you have no rights not even a chance to do so :)
class Base
public: can be accessed by anybody
private: can only be accessed by only base member functions (not
derived classes)
protected: can be accessed by both base member functions and derived
classes
Well, if you have access to base class, you can declare class B as friend class. But as others explained it: because you can, it does not mean it's good idea. Use protected members, if you want derived classes to be able to access them.
It is doable as describe in this Guru of the Week - GotW #76 - Uses and Abuses of Access Rights. But it's should be considered a last resort.
You need to define it as protected. Protected members are inherited to child classes but are not accessible from the outside world.
You can access the private members of a base class say A through an inherited member function of A
#include<iostream>
using namespace std;
class A{
int a;
public:
A(){};
A(int val){a=val;};
int get_a(){//To access a private variable it must be initialized here
a=10;
return a;
}
};
class B: public A{
int b;
public:
B(){};
B(int val){b=val;};
void get(){
cout<<get_a();
}
};
int main(){
A ob1(2);
cout<<ob1.get_a()<<endl;
B ob2(4);
ob2.get();
return 0;
}

Using protected static variable in another file

How can I access a variable that has been declared as static and protected in a class definition for use in another file b.cpp
The only code allowed to use protected class members (static or not) are explicit friends of the class in question and classes derived from the class in question (and of course, members of the class itself). Therefore, if "you" want to access that value, then "you" must either be a friend of that class or a member of a class derived from it.
The protection classes (public, protected, and private) exist to provide protection for data. By declaring the member to be protected, the writer of that class is making a semi-strong statement about what code should be allowed to touch that piece of memory. If you're not a derived class or have been given permission with an explicit friend specification, then you're not allowed to touch it.
You should not derive from a class solely to get access to a protected static member. You should only derive from a class if it makes sense to do so based on what your derived class is trying to do.
Having declared as protected, the static variable can only be accessed with in it's member functions and it's derived classes( public, protected inheritance ).
I faced this once in a class that I can't modify(standard adaptors), and came up with the following solution with the help of SO & Google!
#include <iostream>
class my_type{
protected:
static int var;
};
int my_type::var = 0;
int& get_var(my_type& obj){
class protected_accessor : my_type{
public:
static int& get_var(my_type&){
return my_type::var;
}
};
return protected_accessor::get_var(obj);
}
int main(){
my_type obj;
std::cout << get_var(obj) << std::endl;
get_var(obj) = 1;
std::cout << get_var(obj);
}
I have used a variation of this code in my tiny utility: https://bitbucket.org/AraK/streamer/wiki/Developer_FAQ. Look for "Streaming Standard Adapters".

Why does C++ not allow inherited friendship?

Why is friendship not at least optionally inheritable in C++? I understand transitivity and reflexivity being forbidden for obvious reasons (I say this only to head off simple FAQ quote answers), but the lack of something along the lines of virtual friend class Foo; puzzles me. Does anyone know the historical background behind this decision? Was friendship really just a limited hack that has since found its way into a few obscure respectable uses?
Edit for clarification: I'm talking about the following scenario, not where children of A are exposed to either B or to both B and its children. I can also imagine optionally granting access to overrides of friend functions, etc.
class A {
int x;
friend class B;
};
class B {
// OK as per friend declaration above.
void foo(A& a, int n) { a.x = n; }
};
class D : public B { /* can't get in A w/o 'friend class D' declaration. */ };
Accepted answer: as Loki states, the effect can be simulated more or less by making protected proxy functions in friended base classes, so there is no strict need for granting friendship to a class or virtual method heirarchy. I dislike the need for boilerplate proxies (which the friended base effectively becomes), but I suppose that this was deemed preferable over a language mechanism that would more likely be misused most of the time. I think it's probably time I bought and read Stroupstrup's The Design and Evolution of C++, which I've seen enough people here recommend, to get better insight to these types of questions ...
Because I may write Foo and its friend Bar (thus there is a trust relationship).
But do I trust the people who write classes that are derived from Bar?
Not really. So they should not inherit friendship.
Any change in the internal representation of a class will require a modification to anything that is dependent on that representation. Thus all members of a class and also all friends of the class will require modification.
Therefore if the internal representation of Foo is modified then Bar must also be modified (because friendship tightly binds Bar to Foo). If friendship was inherited then all class derived from Bar would also be tightly bound to Foo and thus require modification if Foo's internal representation is changed. But I have no knowledge of derived types (nor should I. They may even be developed by different companies etc). Thus I would be unable to change Foo as doing so would introduce breaking changes into the code base (as I could not modify all class derived from Bar).
Thus if friendship was inherited you are inadvertently introducing a restriction on the ability to modify a class. This is undesirable as you basically render useless the concept of a public API.
Note: A child of Bar can access Foo by using Bar, just make the method in Bar protected. Then the child of Bar can access a Foo by calling through its parent class.
Is this what you want?
class A
{
int x;
friend class B;
};
class B
{
protected:
// Now children of B can access foo
void foo(A& a, int n) { a.x = n; }
};
class D : public B
{
public:
foo(A& a, int n)
{
B::foo(a, n + 5);
}
};
A friended class may expose its friend through accessor functions, and then grant access through those.
class stingy {
int pennies;
friend class hot_girl;
};
class hot_girl {
public:
stingy *bf;
int &get_cash( stingy &x = *bf ) { return x.pennies; }
};
class moocher {
public: // moocher can access stingy's pennies despite not being a friend
int &get_cash( hot_girl &x ) { return x.get_cash(); }
};
This allows finer control than optional transitivity. For example, get_cash may be protected or may enforce a protocol of runtime-limited access.
C++ Standard, section 11.4/8
Friendship is neither inherited nor transitive.
If friendship would be inherited, then a class that wasn't meant to be a friend would suddenly have access to your class internals and that violates encapsulation.
Because it's just unnecessary.
The usage of the friend keyword is itself suspicious. In term of coupling it's the worst relationship (way ahead of inheritance and composition).
Any change to the internals of a class have a risk to impact the friends of this class... do you really want an unknown number of friends ? You would not even be able to list them if those who inherit from them could be friends also, and you would run in the risk of breaking your clients code each time, surely this is not desirable.
I freely admit that for homework/pet projects dependency is often a far away consideration. On small size projects it doesn't matter. But as soon as several persons work on the same project and this grows into the dozens of thousands of lines you need to limit the impact of changes.
This bring a very simple rule:
Changing the internals of a class should only affect the class itself
Of course, you'll probably affect its friends, but there are two cases here:
friend free function: probably more of a member function anyway (I am think std::ostream& operator<<(...) here, which is not a member purely by accident of the language rules
friend class ? you don't need friend classes on real classes.
I would recommend the use of the simple method:
class Example;
class ExampleKey { friend class Example; ExampleKey(); };
class Restricted
{
public:
void forExampleOnly(int,int,ExampleKey const&);
};
This simple Key pattern allows you to declare a friend (in a way) without actually giving it access to your internals, thus isolating it from changes. Furthermore it allows this friend to lend its key to trustees (like children) if required.
A guess: If a class declares some other class/function as a friend, it's because that second entity needs privileged access to the first. What use is there in granting the second entity privileged access to an arbitrary number of classes derived from the first?
A derived class can inherit only something, which is 'member' of the base. A friend declaration is not a member of the befriending class.
$11.4/1- "...The name of a friend is
not in the scope of the class, and the
friend is not called with the member
access operators (5.2.5) unless it is
a member of another class."
$11.4 - "Also, because the base-clause
of the friend class is not part of its
member declarations, the base-clause
of the friend class cannot access the
names of the private and protected
members from the class granting
friendship."
and further
$10.3/7- "[Note: the virtual specifier
implies membership, so a virtual
function cannot be a nonmember (7.1.2)
function. Nor can a virtual function
be a static member, since a virtual
function call relies on a specific
object for determining which function
to invoke. A virtual function declared
in one class can be declared a friend
in another class. ]"
Since the 'friend' is not a member of the base class in the first place, how can it be inherited by the derived class?
Friend function in a class assigns the extern property to the function. i.e. extern means that the function has been declared and defined somewhere out of the class.
Hence it means friend function is not a member of a class. So the inheritance only allows you to inherit the properties of a class not external things. And also if inheritance is allowed for friend functions, then a third party class inheriting.
Friend is good in inheritance like style interface for container
But for me, as the first say, C++ lack the propagatable inheritance
class Thing;
//an interface for Thing container's
struct IThing {
friend Thing;
protected:
int IThing_getData() = 0;
};
//container for thing's
struct MyContainer : public IThing {
protected: //here is reserved access to Thing
int IThing_getData() override {...}
};
struct Thing {
void setYourContainer(IThing* aContainerOfThings) {
//access to unique function in protected area
aContainerOfThings->IThing_getData(); //authorized access
}
};
struct ChildThing : public Thing {
void doTest() {
//here the lack of granularity, you cannot access to the container.
//to use the container, you must implement all
//function in the Thing class
aContainerOfThings->IThing_getData(); //forbidden access
}
};
For me the problem of C++ is the lack of very good granularity to
control all access from anywhere for anything :
friend Thing can become friend Thing.* to grant access to all child of Thing
And more, friend [named area] Thing.* to grant access for a precise
are in the Container class via special named area for the friend.
Ok stop the dream. But now, you know an interesting usage of friend.
In another order, you can also found interesting to known all class are friendly with self. In other word, a class instance can call all
members of another instance of same name without restriction:
class Object {
private:
void test() {}
protected:
void callAnotherTest(Object* anotherObject) {
//private, but yes you can call test() from
//another object instance
anotherObject)->test();
}
};
Simple logic : 'I have a friend Jane. Just because we became friends yesterday does not make all of her friends mine.'
I still need to approve those individual friendships, and the level of trust would be accordingly.