Related
I have an abstract class base with private member variable base_var. I want to create a derived class, which also has base_var as a private member.
To me, this seems like an obvious thing you would want to do. base is abstract so it will never be instantiated. The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
However, the below diagram seems to suggest that this is not doable with inheritance?
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
However, the below diagram seems to suggest that this is not doable with inheritance?
Correct, private members of a class can not be accessed by derived classes. If You want a member of a class to be accessible by its derived classes but not by the outside, then You have to make it protected.
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
Even an abstract class can have member functions which act on a (private) member variable. Consider (somewhat silly example, but well):
class MaxCached
{
private:
int cache = std::numeric_limits<int>::min();
public:
bool put(int value)
{
if (value > cache)
{
cache = value;
return true;
}
return false;
}
int get() const
{
return cache;
}
virtual void someInterface() const = 0;
};
Deriving from this class gives You the functionality of the base class (put and get) without the danger of breaking it (by for example writing a wrong value to cache).
Side note: Above is a purely made up example! You shouldn't add such a cache (which is independent of Your interface) into the abstract base class. As it stands the example breaks with the "Single Responsibility Principle"!
Just because a class is abstract doesn't mean there cannot be code implemented in that class that might access that variable. When you declare an item in a class to be private, the compiler assumes you had a good reason and will not change the access just because it there is a pure virtual function in the class.
If you want your derived classes to have access to a base class member declare the member as protected.
I have an abstract class base with private member variable base_var
class foo {
public:
virtual void a_pure_virtual_method() = 0;
int get_var() { base_var; }
virtual ~foo(){}
private:
int base_var;
};
Note that a class is said to be abstract when it has at least one pure virtual (aka abstract) method. There is nothing that forbids an abstract class to have non-pure virtual or even non-virtual methods.
I want to create a derived class, which also has base_var as a private member.
class derived : public foo {};
To me, this seems like an obvious thing you would want to do.
Sure, no problem so far.
The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
Still fine.
Why not?
You are confusing access rights that are display in the image you included with the mere presence of the members in the derived. The derived class has no access to members that are private in the base class. Period. This is just according to the definition of what is private.
What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
It is not useless at all. Derived classes inherit all members, they just cannot access all of them. The private stuff is there you just cannot access it directly. Thats the whole point of encapsulation. Consider this example:
class bar : public foo {
void test() {
std::cout << base_var; // error base_var is private in foo
std::cout << get_var(); // fine
}
};
guys, I encountered this problem on a tech blog,the question asked what are the correct solution to resolve the compiler error generated in the below code. I have searched for hours and can not get an answer.
class SomeClass
{
public:
int data;
protected:
class Nest
{
public:
int nested;
};
public:
static Nest* createNest(){return new Nest;}
};
void use_someclass()
{
SomeClass::Nest* nst = SomeClass::createNest();
nst->nested = 5;
}
A. Make function void use_someclass() a friend of class SomeClass.
B. Make the function createNest() a non-static function of SomeClass.
C. Declare the class Nest in public scope of class SomeClass.
D. Make the object nst a reference object, and make the function
createNest() return a Nest&.
E. Derive a class from SomeClass. Make the object nst a derived class
pointer so that it can access SomeClass's protected declarations.
C is certainly right and trival.
I believe A is also right, and espectially E is a classic way of doing this kind of things.
I want implement what is said in E, but have a few difficulites. (I hope someone can also implement the idea in A), below is my code:
class derived:public SomeClass{};
void use_someclass()
{
derived::Nest *nst=SomeClass::createNest();
nst->nested = 5;
}
in the above, the idea is we can access the Nest definition from a derived class.
in function use_someclass(), in the first line, the right hand side is a static function, and returns type Nest*, but on the left hand side, I don't know how to match the right hand side type. "derived::Nest" is wrong. compiler error: can not access protected member. Nest is only a definition in SomeClass, not member.
what can we use to replace "derived::Nest"? derived certainly saw the definition of Nest, but I don't know how to "say" it. Maybe somehow via "this" pointer.
You can change the visibility in your derived class:
class derived : public SomeClass {
public:
using SomeClass::Nest;
}
My code:-
#include<iostream>
using namespace std;
class a{
private:
int x;
public:
a(int data)
{
x=data;
}
friend void printPrivateMember(a);
};
void printPrivateMember(a obj)
{
cout<<obj.x; //I can access private data member by an object inside this function.
}
int main()
{
a obj1(5);
printPrivateMember(obj1);
cout<<obj1.x; //this gives error
return 0;
}
I wanted to know as to how can I access a PRIVATE data type by an object in the friend function but cannot do so in main.
When I read about access specifier . It was specified that private can be accessed by only member functions (I don't have a problem with the friend function) and not by the object of that class. I wanted to know as to what difference is there because of which I can access private member by an object in one case and cannot do so in another. The same is applicable for copy constructor.
That's exactly what friend functions do: any friend function of a class can access it's private members. Since your printPrivateMember is declared as a friend of a, it can access it's private x member. Since main is not a friend function, it can't.
Forestalling a question about declaring main as friend, this question covers it.
Because friends could do that.
$11/1 Member access control [class.access]
(emphasis mine)
1 A member of a class can be
(1.1) — private; that is, its name can be
used only by members and friends of the class in which it is
declared.
(1.2) — protected; that is, its name can be used only by
members and friends of the class in which it is declared, by classes
derived from that class, and by their friends (see 11.4).
(1.3) —
public; that is, its name can be used anywhere without access
restriction.
As you correctly observed, only member functions (including constructors and destructors) and friend functions and classes may access you're privates. That's the purpose of friends: they provide an exception (not std::exception) to the encapsulation mechanism.
Now you may think about whether this breaks encapsulation or actually stabilizes it.
if you want to access private member, you'd better use a public function like:
class a {
private:
int m;
public:
int getM() {
return m;
}
};
Your use of the phrase not by the object of that class makes me think that you are unclear on the access rules. The access rules don't apply to the objects but who can access member variables and member functions of the objects.
A member variable of a class can be accessed in a function -- which can be a member function of the class, a member function of another class, or a global function.
It can also be accessed in the global space, e.g. to initialize a global variable.
A friend declaration in a class changes the default access rules that are in place by use of private, protected, and public access specifiers.
A function declared a friend of a class can access all the members of all instances of the class.
The answer by songyuanyao cites the section of the standard that provides more details on the subject.
This function should be public, so that you can access it through main().
void print(){
/**print or return your private variable here**/
}
Basically as far as I know, when you create a base class with a public, protected, and private section and variables/functions in each the public and protected sections will get inherited into the appropriate section of the sub-class (defined by class subclass : private base, which will take all public and protected members of base and put them into public, changing the word private to public puts them all in public and changing it to protected puts them all into protected).
So, when you create a sub-class you never receive anything from the private section of the previous class (the base class in this case), if this is true then an object of the sub-class should never have it's own version of a private variable or function from the base class correct?
Let's run over an example:
#include <iostream>
class myClass // Creates a class titled myClass with a public section and a private section.
{
public:
void setMyVariable();
int getMyVariable();
private:
int myVariable; // This private member variable should never be inherited.
};
class yourClass : public myClass {}; // Creates a sub-class of myClass that inherits all the public/protected members into the
// public section of yourClass. This should only inherit setMyVariable()
// and getMyVariable() since myVariable is private. This class does not over-ride any
// functions so it should be using the myClass version upon each call using a yourClass
// object. Correct?
int main()
{
myClass myObject; // Creates a myClass object called myObject.
yourClass yourObject; // Creates a yourClass object called yourObject
yourObject.setMyVariable(); // Calls setMyVariable() through yourObject. This in turn calls the myClass version of it because
// there is no function definition for a yourClass version of this function. This means that this
// can indeed access myVariable, but only the myClass version of it (there isn't a yourClass
// version because myVariable is never inherited).
std::cout << yourObject.getMyVariable() << std::endl; // Uses the yourClass version of getMyVariable() which in turn
// calls the myClass version, thus it returns the myClass myVariable
// value. yourClass never has a version of myVariable Correct?
std::cout << myObject.getMyVariable() << std::endl; // Calls the myClass version of getMyVariable() and prints myVariable.
return 0;
}
void myClass::setMyVariable()
{
myVariable = 15; // Sets myVariable in myClass to 15.
}
int myClass::getMyVariable()
{
return myVariable; // Returns myVariable from myClass.
}
Now, in theory based on what I think, this should print:
15
15
Due to it simply always using the myClass version of the functions (thus using the myClass myVariable). But, strangely, this is not the case. The result of running this program prints:
15
0
This makes me wonder, are we actually not only inheriting myVariable, but do we also have the ability to mess around with it? Clearly this is creating an alternate version of myVariable somehow otherwise there wouldn't be a 0 for the myClass version. We are indeed editing a second copy of myVariable by doing all this.
Can someone please explain this all to me, this has torn apart my understanding of inheritance.
Basically as far as I know, when you create a base class with a public, protected, and private section and variables/functions in each the public and protected sections will get inherited into the appropriate section of the sub-class (defined by class subclass : private base, which will take all public and private members of base and put them into public, changing the word private to public puts them all in public and changing it to protected puts them all into protected).
There's a bit of confusion in this statement.
Recall that inheritance is defined for classes and structs in C++. Individual objects (ie. instances) do not inherit from other objects. Constructing an object using other objects is called composition.
When a class inherits from another class, it gets everything from that class, but the access level of the inherited fields may inhibit their use within the inheritor.
Furthermore, there are 3 kinds of inheritance for classes: private (which is the default), protected, and public. Each of them changes the access level of a class properties and methods when inherited by a subclass.
If we order the access levels in this manner: public, protected, private, from the least protected to the most protected, then we can define the inheritance modifiers as raising the access levels of the inherited class fields to at least the level they designate, in the derived class (ie. the class inheriting).
For instance, if class B inherits from class A with the protected inheritance modifier:
class B : protected A { /* ... */ };
then all the fields from A will have at least the protected level in B:
public fields become protected (public level is raised to protected),
protected fields stay protected (same access level, so no modification here),
private fields stay private (the access level is already above the modifier)
"When you create a sub-class you never receive anything from the private section of the [base class]. If this is true then an object of the sub-class should never have it's own version of a private variable or function from the base class, correct?"
No. The derived class inherits all the members of the base class, including the private ones. An object of the inherited class has those private members, but does not have direct access to them. It has access to public members of the base class that may have access to those members, but it (the derived class) may not have new member functions with such access:
class yourClass : public myClass
{
public:
void playByTheRules()
{
setMyVariable(); // perfectly legal, since setMyVariable() is public
}
void tamperWithMyVariable()
{
myVariable = 20; // this is illegal and will cause a compile-time error
}
};
myObject and yourObject are two different objects! Why should they share anything?
Think about it that way: Forget about inheritance and suppose you have a class Person with private int age; and public void setAge (int age) {...}. You then instantiate two objects:
Person bob;
Person bill;
bob.setAge(35);
Would you expect Bill to be 35 now, too? You wouldn't, right? Similarly, your myObject doesn't share its data with yourObject.
In response to your comment:
The class yourClass inherits from myClass. That means that both yourObject and myObject have their own myVariable, the latter obviously by definition, the former inherited from myClass.
Physically, every single member( including member functions) of base class goes into the subclass. Doesn't matter if they are private. Doesn't matter if you inherit them publically/protected-ly/privately. So in your example, yourClass contains all three of getMyVariable(), setMyVariable() and myVariable. All this is pretty simple, okay?
What matters is how we can access them. It is like when a file is deleted on your system. So, you should first understand the difference between a member being not there and a member being there but inaccessible. Assume for now that all inheritance takes place publically. Then, all public members of base class are public in derived class, protected members are protected and private members are inaccessible. They are inaccessible and not non-existent because there can be some member functions in protected and public sections in base class which access the private members of base class. Thus, we need all those private members of base which are accessed by public and protected member functions of base, for their functionality. Since there is no way that we can determine which member is needed by which member function in a simple manner, we include all private members of the base class in derived class. All this simply means that in a derived class, a private member can be modified by only through the base class' member functions.
Note: every private member has to be accessed, directly or indirectly [through another private member function which in turn is called by a public/protected member function] by a public/protected meber function, else it has no use.
So, we know till now that a private member variable of base class has its use in derived class i.e. for the functionality of its public/protected member functions. But they can't be accessed directly in base class.
Now, we turn our attention to private/public inheritance. For public inheritance, it means that all the accessible members of base class (that is, the public and protected members) can not be at a level more permissive than public. Since, public is the most permissive level, public and protected members remain public. But at protected and private inheritance, both become protected and private in the derived class, respectively. Inthe latter case, since all these members are private, they can't be accessed further in the hierarchy chain, but can be accessed by the given derived class all the same.
Thus, the level of each base class member in derived class is the lesser of their level in derived class () and the type of inheritance (public/protected/private).
Same concept applies to the functions outside the class. For them private and protected members are inaccessible but they do exist and can be accessed by the public member functions.
And taking your case as a final example, setMyvariable() and getMyVariable() can access myVariable in the derived class. But no function specified in derived class can access myVariable. Modifying your class:
class myClass
{
public:
void setMyVariable();
int getMyVariable();
private:
int myVariable;
};
class yourClass : public myClass
{
public:
// void yourFunction() { myVariable = 1; }
/*Removing comment creates error; derived class functions can't access myVariable*/
};
Further: you can add exceptions to the type of inheritance too e.g. a private inheritance except a member made public in derived class. But that is another question altogether.
You never call myObject.setMyVariable(), so myObject.getMyVariable() will not return 15.
private does not imply static.
After:
class yourClass : public myClass {};
there is still only one member variable. But there are two ways of accessing it by name: myClass::myVariable, and yourClass::myVariable.
In these expressions, the class name is known as the naming class. The second key thing to understand is that access rights apply to the combination of naming class and member name; not just to the member name and not to the variable itself.
If a member is mentioned without explicitly having the naming class present, then the naming class is inferred from the type of the expression on the left of the . or -> that named the member (with this-> being implied if there is no such expression).
Furthermore, there are really four possible types of access: public, protected, private, and no access. You can't declare a member as having no access, but that situation arises when a private member is inherited.
Applying all this theory to your example:
The name myClass::myVariable is private.
The name yourClass::myVariable is no access.
To reiterate, there is only actually one variable, but it may be named in two different ways, and the access rights differ depending on which name is used.
Finally, back to your original example. myObject and yourObject are different objects. I think what you intended to write, or what you are mentally imagining is actually this situation:
yourClass yourObject;
myClass& myObject = yourObject;
// ^^^
which means myObject names the base class part of yourObject. Then after:
yourObject.setMyVariable();
the variable is set to 15, and so
std::cout << myObject.getMyVariable() << std::endl;
would output 15 because there is indeed only one variable.
This may help
#include<iostream>
using namespace std;
class A
{
int b;
};
class B : private A
{
};
int main()
{
C obj;
cout<<sizeof(obj);
return 0;
}
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.