Base class access specification vs class member access specification [duplicate] - c++

This question already has answers here:
What are access specifiers? Should I inherit with private, protected or public?
(2 answers)
Closed 10 years ago.
How is base class access specification different from member access specification?

Base class access specification decides about base class' members access specification in your class. They provide a way to hide base class' members if you don't want them to appear publicly in your class. They doesn't affect visibility of members of your class though.
C++ FAQ explains this issue quite nicely.
class Base
{
protected:
int A;
public:
int B;
};
class Derived1 : public Base
{
// Derived1::A outside class is seen as protected
// Derived1::B outside class is seen as public
};
class Derived2 : protected Base
{
// Derived1::A outside class is seen as protected
// Derived1::B outside class is seen as protected
};
class Derived3 : private Base
{
// Derived1::A outside class is seen as private
// Derived1::B outside class is seen as private
};

Related

Class member visibility within inheritance c++ [duplicate]

This question already has answers here:
What is the difference between public, private, and protected inheritance in C++?
(16 answers)
Closed 4 months ago.
This post was edited and submitted for review 4 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I was looking up some unknown book about C++. and faced with this table which title reads.
" ― As the result of inheritance all fields of base class are being inherited by derived class."
And then it shows such table.
My question is:
Are private fields and functions from base class accessible (as noted in the confusing table) by derived class during private inheritance?
I have read ISO C++ standard, and there is no any mentions about private fields and private inheritance combined, though I have tried myself to find out, and the code behaves as it supposed to.
Example I used.
#include <iostream>
using namespace std;
class BASE
{
private:
int x;
};
class DERIVED : private BASE
{
public:
void print_X(void){cout << x << "\n";}
};
int main()
{
return 0;
}
Then compiler error message says:
main.cpp:23:36: error: ‘int BASE::x’ is private within this context
23 | void print_X(void){cout << x << "\n";}
So now I wonder, whether I do something wrong, or the publisher of that book should correct that pages?!
The table you have is a bit confusing.
Public inheritance makes public members of the base class public in the derived class, and the protected members of the base class remain protected in the derived class.
Protected inheritance makes the public and protected members of the base class protected in the derived class.
Private inheritance makes the public and protected members of the base class private in the derived class.
class Base {
public:
int x;
protected:
int y;
private:
int z;
};
class PublicDerived: public Base {
/*
x is public
y is protected
z is not accessible from PublicDerived
*/
};
class ProtectedDerived: protected Base {
/*
x is protected
y is protected
z is not accessible from ProtectedDerived
*/
};
class PrivateDerived: private Base {
/*
x is private
y is private
z is not accessible from PrivateDerived
*/
};
That table is misleading but technically correct. It tells you what other classes can access in the derived class, not what the derived class can access in the base class.
A derived class can access public and protected members of its base class. That's what public and protected mean (on top of public meaning everyone else has access). However, it still contains the private members of its base class, it just can't access them.
If the inheritence is private, then from the point of view of the derived class, all the members of its base class are private, so it can't access them and nobody outside can either (from the derived class). However, a derived class could still create a variable of its base class and access its public (but not protected) members, as could any other class.
If the inheritence is protected, then from the point of view of the derived class, all the public members of its base class are protected, so it can access them but nobody outside can.
To show that private members of the base class are still part of the derived class, you can try this (undefined behavior):
class DERIVED : private BASE
{
public:
void print_X(void) { std::cout << *reinterpret_cast<int*>(this) << "\n";}
};
Demo
From the C++ 17 Standard (13 Derived classes)
...Unless redeclared in the derived class, members of a base class are
also considered to be members of the derived class. Members of a base
class other than constructors are said to be inherited by the derived
class. Constructors of a base class can also be inherited as described
in 10.3.3. Inherited members can be referred to in expressions in the
same manner as other members of the derived class, unless their names
are hidden or ambiguous
and (13.2 Member name lookup)
1 Member name lookup determines the meaning of a name (id-expression)
in a class scope (6.3.7). Name lookup can result in an ambiguity, in
which case the program is ill-formed. For an id-expression, name
lookup begins in the class scope of this; for a qualified-id, name
lookup begins in the scope of the nested-name-specifier. Name lookup
takes place before access control (6.4, Clause 14).
So even private members of a base class are members of its derived class.

Unable to access protected data of the superclass from within the subclass when it's a different object passed as a pointer [duplicate]

This question already has answers here:
Accessing protected members in a derived class
(8 answers)
Closed 3 years ago.
I'm trying several programs about inheritance, and it turned out that the following caused an error but I don't really know the rationale.
#include <iostream>
using namespace std;
class Base {
protected:
int x = 0;
};
class Derived: public Base {
// OK: access protected member via this
void g() { cout<<x; }
// OK: access protected member of other Derived
void h(Derived& d) { cout<<d.x; }
// FAIL: access Base class's protected member, why?
void f(Base& b) { cout<<b.x; }
};
int main() {}
I expect that the Derived class could access the ​Base class's public or protected data members and member function.
However it didn't work as what I was thinking about, could anyone help me light up my concepts?
There is not more to it than you already discovered. Derived instances may acces their protected members and those of other derived instances but not those of base class instances. Why? Because thats how protected works by definition.
For more details I refer you to cppreference (emphasize mine):
A protected member of a class Base can only be accessed
1) by the members and friends of Base
2) by the members and friends (until
C++17) of any class derived from Base, but only when operating on an
object of a type that is derived from Base (including this)
void f(Base& b) {cout<<b.x;}
Here you are trying to access a protected member of a different class. It does not matter that you also share the same base class. (still looking for a source)
void g() {cout<<x;}
In this example you are acccessing your own private member. (protected members of base class are inherited and protected in derived class)
void h(Derived& d) {cout<<d.x;}
Here you are accessing the private member of the same class. But for more on this look at this post: Access private elements of object of same class
From this documentation
A protected member of a class Base can only be accessed
by the members and friends of Base
this is not your case
by the members and friends (until
C++17) of any class derived from Base, but only when operating on an
object of a type that is derived from Base (including this)
this is your case, but the argument b is not such a derived type
The reason for protected member access is to allow a base class to define an interface for use by derived classes. That's not the same as allowing every different derived type special access to every base class object.
The code in your question seems like the example in the cppreference website and there we can see a good explanation for that limitation in the code comments:
struct Base {
protected:
int i;
private:
void g(Base& b, struct Derived& d);
};
struct Derived : Base {
void f(Base& b, Derived& d) // member function of a derived class
{
++d.i; // okay: the type of d is Derived
++i; // okay: the type of the implied '*this' is Derived
// ++b.i; // error: can't access a protected member through Base
// (Otherwise it would be possible to change other derived classes,
// like a hypothetical Derived2, base implementation)
}
};
So, if you have a
class Derived2: public Base {
};
The Derived class shall not be allowed to access Derived2 protected attributes as it is not a child of Derived2. The purpose of protected is not to allow siblings but children class access to members.
Full details in the standard:
http://eel.is/c++draft/class.access#:access_control,protected
http://eel.is/c++draft/class.access#class.protected

How can I access base class's protected members through derived class? [duplicate]

This question already has answers here:
Accessing protected members in a derived class
(8 answers)
Closed 3 years ago.
I'm trying several programs about inheritance, and it turned out that the following caused an error but I don't really know the rationale.
#include <iostream>
using namespace std;
class Base {
protected:
int x = 0;
};
class Derived: public Base {
// OK: access protected member via this
void g() { cout<<x; }
// OK: access protected member of other Derived
void h(Derived& d) { cout<<d.x; }
// FAIL: access Base class's protected member, why?
void f(Base& b) { cout<<b.x; }
};
int main() {}
I expect that the Derived class could access the ​Base class's public or protected data members and member function.
However it didn't work as what I was thinking about, could anyone help me light up my concepts?
There is not more to it than you already discovered. Derived instances may acces their protected members and those of other derived instances but not those of base class instances. Why? Because thats how protected works by definition.
For more details I refer you to cppreference (emphasize mine):
A protected member of a class Base can only be accessed
1) by the members and friends of Base
2) by the members and friends (until
C++17) of any class derived from Base, but only when operating on an
object of a type that is derived from Base (including this)
void f(Base& b) {cout<<b.x;}
Here you are trying to access a protected member of a different class. It does not matter that you also share the same base class. (still looking for a source)
void g() {cout<<x;}
In this example you are acccessing your own private member. (protected members of base class are inherited and protected in derived class)
void h(Derived& d) {cout<<d.x;}
Here you are accessing the private member of the same class. But for more on this look at this post: Access private elements of object of same class
From this documentation
A protected member of a class Base can only be accessed
by the members and friends of Base
this is not your case
by the members and friends (until
C++17) of any class derived from Base, but only when operating on an
object of a type that is derived from Base (including this)
this is your case, but the argument b is not such a derived type
The reason for protected member access is to allow a base class to define an interface for use by derived classes. That's not the same as allowing every different derived type special access to every base class object.
The code in your question seems like the example in the cppreference website and there we can see a good explanation for that limitation in the code comments:
struct Base {
protected:
int i;
private:
void g(Base& b, struct Derived& d);
};
struct Derived : Base {
void f(Base& b, Derived& d) // member function of a derived class
{
++d.i; // okay: the type of d is Derived
++i; // okay: the type of the implied '*this' is Derived
// ++b.i; // error: can't access a protected member through Base
// (Otherwise it would be possible to change other derived classes,
// like a hypothetical Derived2, base implementation)
}
};
So, if you have a
class Derived2: public Base {
};
The Derived class shall not be allowed to access Derived2 protected attributes as it is not a child of Derived2. The purpose of protected is not to allow siblings but children class access to members.
Full details in the standard:
http://eel.is/c++draft/class.access#:access_control,protected
http://eel.is/c++draft/class.access#class.protected

What is difference between protected and private derivation in c++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between private, public and protected inheritance in C++
What is difference between deriving as protected or private in c++? i am not able to figure out, since both seem to restrict base class member access from derived class object
Let's consider a code example showing what would be allowed (or not) using different levels of inheritance:
class BaseClass {};
void freeStandingFunction(BaseClass* b);
class DerivedProtected : protected BaseClass
{
DerivedProtected()
{
freeStandingFunction(this); // Allowed
}
};
DerivedProtected can pass itself to freeStandingFunction because it knows it derives from BaseClass.
void freeStandingFunctionUsingDerivedProtected()
{
DerivedProtected nonFriendOfProtected;
freeStandingFunction(&nonFriendOfProtected); // NOT Allowed!
}
A non-friend (class, function, whatever) cannot pass a DerivedProtected to freeStandingFunction, because the inheritance is protected, so not visible outside derived classes. Same goes for private inheritance.
class DerivedFromDerivedProtected : public DerivedProtected
{
DerivedFromDerivedProtected()
{
freeStandingFunction(this); // Allowed
}
};
A class derived from DerivedProtected can tell that it inherits from BaseClass, so can pass itself to freeStandingFunction.
class DerivedPrivate : private BaseClass
{
DerivedPrivate()
{
freeStandingFunction(this); // Allowed
}
};
The DerivedPrivate class itself knows that it derives from BaseClass, so can pass itself to freeStandingFunction.
class DerivedFromDerivedPrivate : public DerivedPrivate
{
DerivedFromDerivedPrivate()
{
freeStandingFunction(this); // NOT allowed!
}
};
Finally, a non-friend class further down the inheritance hierarchy cannot see that DerivedPrivate inherits from BaseClass, so cannot pass itself to freeStandingFunction.
Use this matrix (taken from here) to decide the visibility of inherited members:
inheritance\member | private | protected | public
--------------------+-----------------+---------------+--------------
private | inaccessible | private | private
protected | inaccessible | protected | protected
public | inaccessible | protected | public
--------------------+-----------------+---------------+--------------
Example 1:class A { protected: int a; }
class B : private A {}; // 'a' is private inside B
Example 2:
class A { public: int a; }
class B : protected A {}; // 'a' is protected inside B
Example 3:
class A { private: int a; }
class B : public A {}; // 'a' is inaccessible outside of A
private allows only the class it is declared in to access it
protected allows that class and derived/sub classes to access as if it were private
I had added a very detailed explanation about Inheritance & Access Specifiers in this Q. It explains all the types of Inheritance and how access specifiers work with each of them. Do have a look.
Hth :)
Basically, protected inheritance extends further down the inheritance hierarchy than does private inheritance. See the C++ FAQ Lite for details.

why does the derived class inherit the private members of the base class? [duplicate]

This question already has answers here:
Do Sub-Classes Really Inherit Private Member Variables?
(7 answers)
Closed 5 years ago.
I know that the derived class can't access the private members of the base class, so why does the derived class inherit the private members of the base class? Is there any case that it is useful?
Thanks!
The derived class needs the private members even though it can't access them directly. Otherwise it's behavior would not build on the class it is deriving from.
For example, pretend the private stuff is:
int i;
and the class has a geti() and seti(). The value of i has to be put somewhere, even if it is private,
The public and protected methods of the base class can still access private variables of the base class, and these methods are available in the derived class.
The base class can still use the private member variables & methods.
If you want the derived classes to have access to members but keep those members hidden from the outside world, make them protected:.
Here's an example to illustrate:
class Base
{
public:
Base() : val(42.0f) {};
float GetValue() const
{
return val_;
}
private:
float val_;
};
class Derived : public Base
{
public:
float ComputedValue() const
{
return GetValue() * 2.0f;
}
};
Don't forget that the base class may have methods that are not private, and thus accessible by the derived class. Those protected or public base class methods can still invoke the private base class methods. This is particularly useful if you want to lock down core functionality in the base class, such as with a Template Method design pattern implementation:
class base
{
public:
virtual ~base() { /* ... */ }
virtual void base_func() { foo_private (); }
virtual void do_func() = 0;
private:
void foo_private()
{
// pre-do_func() operations
do_func();
// post-do_function operations
}
};
class derived : public base
{
public:
void derived_func() { base_func(); }
virtual void do_func()
{
// Derived class specific operations
}
};
The reason is because derived classes have an is-a relationship to the superclass.
A derived class instantiation IS A superclass instantiation...just with more (or less due to setting some superclass functions private) stuff.
As has been outlined by other answers here, the derived class syntactically cannot access the private members of the base class; but it needs to have a copy of the same in its memory layout. Think of casting. using 'C' casting you can cast a derived to a private base. The compiler would then need the correct memory offset in order to produce a valid memory-layout for the base object.
Ex.
class Base {
public:
void printA() {
a = 10;
std::cout << a << std::endl;
}
private:
int a;
};
class Derived : private Base{
int b;
};
Derived* d = new Derived;
Base* b = (Base*)d;
b->printA();
The derived class doesn't "inherit" the private members of the base class in any way - it can't access them, so it doesn't "inherit" them.
An instance of the derived class contains instances of the private members of the base class, for obvious reasons.
So I don't even know what you mean by that question.
when derived class object is created, base class constructor is also called for base object creation. if private members of base class are not allocated memory , the base object will be incomplete.
hence derived class object inherits private members of base, as they are created during creation of base class object, but are not accessible as they are private.
Although the private members are not accessible from the base class, they are inherited by them because these properties are used by the derived class with the help of non-private functions.
Private members of the base class are not directly accessed, but derived by base class by derived class.