Related
What is the difference between public, private, and protected inheritance in C++?
All of the questions I've found on SO deal with specific cases.
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A // 'private' is default for classes
{
// x is private
// y is private
// z is not accessible from D
};
IMPORTANT NOTE: Classes B, C and D all contain the variables x, y and z. It is just question of access.
About usage of protected and private inheritance you could read here.
To answer that question, I'd like to describe member's accessors first in my own words. If you already know this, skip to the heading "next:".
There are three accessors that I'm aware of: public, protected and private.
Let:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
Everything that is aware of Base is also aware that Base contains publicMember.
Only the children (and their children) are aware that Base contains protectedMember.
No one but Base is aware of privateMember.
By "is aware of", I mean "acknowledge the existence of, and thus be able to access".
next:
The same happens with public, private and protected inheritance. Let's consider a class Base and a class Child that inherits from Base.
If the inheritance is public, everything that is aware of Base and Child is also aware that Child inherits from Base.
If the inheritance is protected, only Child, and its children, are aware that they inherit from Base.
If the inheritance is private, no one other than Child is aware of the inheritance.
Limiting the visibility of inheritance will make code not able to see that some class inherits another class: Implicit conversions from the derived to the base won't work, and static_cast from the base to the derived won't work either.
Only members/friends of a class can see private inheritance, and only members/friends and derived classes can see protected inheritance.
public inheritance
IS-A inheritance. A button is-a window, and anywhere where a window is needed, a button can be passed too.
class button : public window { };
protected inheritance
Protected implemented-in-terms-of. Rarely useful. Used in boost::compressed_pair to derive from empty classes and save memory using empty base class optimization (example below doesn't use template to keep being at the point):
struct empty_pair_impl : protected empty_class_1
{ non_empty_class_2 second; };
struct pair : private empty_pair_impl {
non_empty_class_2 &second() {
return this->second;
}
empty_class_1 &first() {
return *this; // notice we return *this!
}
};
private inheritance
Implemented-in-terms-of. The usage of the base class is only for implementing the derived class. Useful with traits and if size matters (empty traits that only contain functions will make use of the empty base class optimization). Often containment is the better solution, though. The size for strings is critical, so it's an often seen usage here
template<typename StorageModel>
struct string : private StorageModel {
public:
void realloc() {
// uses inherited function
StorageModel::realloc();
}
};
public member
Aggregate
class pair {
public:
First first;
Second second;
};
Accessors
class window {
public:
int getWidth() const;
};
protected member
Providing enhanced access for derived classes
class stack {
protected:
vector<element> c;
};
class window {
protected:
void registerClass(window_descriptor w);
};
private member
Keep implementation details
class window {
private:
int width;
};
Note that C-style casts purposely allows casting a derived class to a protected or private base class in a defined and safe manner and to cast into the other direction too. This should be avoided at all costs, because it can make code dependent on implementation details - but if necessary, you can make use of this technique.
These three keywords are also used in a completely different context to specify the visibility inheritance model.
This table gathers all of the possible combinations of the component declaration and inheritance model presenting the resulting access to the components when the subclass is completely defined.
The table above is interpreted in the following way (take a look at the first row):
if a component is declared as public and its class is inherited as public the resulting access is public.
An example:
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
The resulting access for variables p, q, r in class Subsub is none.
Another example:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
The resulting access for variables y, z in class Sub is protected and for variable x is none.
A more detailed example:
class Super {
private:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
int main(void) {
Super object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Now lets define a subclass:
class Sub : Super { };
int main(void) {
Sub object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
The defined class named Sub which is a subclass of class named Super or that Sub class is derived from the Super class.
The Sub class introduces neither new variables nor new functions. Does it mean that any object of the Sub class inherits all the traits after the Super class being in fact a copy of a Super class’ objects?
No. It doesn’t.
If we compile the following code, we will get nothing but compilation errors saying that put and get methods are inaccessible. Why?
When we omit the visibility specifier, the compiler assumes that we are going to apply the so-called private inheritance. It means that all public superclass components turn into private access, private superclass components won't be accessible at all. It consequently means that you are not allowed to use the latter inside the subclass.
We have to inform the compiler that we want to preserve the previously used access policy.
class Sub : public Super { };
Don’t be misled: it doesn’t mean that private components of the Super
class (like the storage variable) will turn into public ones in a
somewhat magical way. Private components will remain private, public
will remain public.
Objects of the Sub class may do "almost" the same things as their older siblings created from the Super class. "Almost" because the fact of being a subclass also means that the class lost access to the private components of the superclass. We cannot write a member function of the Sub class which would be able to directly manipulate the storage variable.
This is a very serious restriction. Is there any workaround?
Yes.
The third access level is called protected. The keyword protected means that the component marked with it behaves like a public one when used by any of the subclasses and looks like a private one to the rest of the world. -- This is true only for the publicly inherited classes (like the Super class in our example) --
class Super {
protected:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
class Sub : public Super {
public:
void print(void) {cout << "storage = " << storage;}
};
int main(void) {
Sub object;
object.put(100);
object.put(object.get() + 1);
object.print();
return 0;
}
As you see in the example code we a new functionality to the Sub class and it does one important thing: it accesses the storage variable from the Super class.
It wouldn’t be possible if the variable was declared as private.
In the main function scope the variable remains hidden anyway so if you write anything like:
object.storage = 0;
The compiler will inform you that it is an error: 'int Super::storage' is protected.
Finally, the last program will produce the following output:
storage = 101
It has to do with how the public members of the base class are exposed from the derived class.
public -> base class's public members will be public (usually the default)
protected -> base class's public members will be protected
private -> base class's public members will be private
As litb points out, public inheritance is traditional inheritance that you'll see in most programming languages. That is it models an "IS-A" relationship. Private inheritance, something AFAIK peculiar to C++, is an "IMPLEMENTED IN TERMS OF" relationship. That is you want to use the public interface in the derived class, but don't want the user of the derived class to have access to that interface. Many argue that in this case you should aggregate the base class, that is instead of having the base class as a private base, make in a member of derived in order to reuse base class's functionality.
Member in base class : Private Protected Public
Inheritance type : Object inherited as:
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
1) Public Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected members of Base class remain protected in Derived class.
c. Public members of Base class remain public in Derived class.
So, other classes can use public members of Base class through Derived class object.
2) Protected Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected members of Base class remain protected in Derived class.
c. Public members of Base class too become protected members of Derived class.
So, other classes can't use public members of Base class through Derived class object; but they are available to subclass of Derived.
3) Private Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected & public members of Base class become private members of Derived class.
So, no members of Base class can be accessed by other classes through Derived class object as they are private in Derived class. So, even subclass of Derived
class can't access them.
Public inheritance models an IS-A relationship. With
class B {};
class D : public B {};
every D is a B.
Private inheritance models an IS-IMPLEMENTED-USING relationship (or whatever that's called). With
class B {};
class D : private B {};
a D is not a B, but every D uses its B in its implementation. Private inheritance can always be eliminated by using containment instead:
class B {};
class D {
private:
B b_;
};
This D, too, can be implemented using B, in this case using its b_. Containment is a less tight coupling between types than inheritance, so in general it should be preferred. Sometimes using containment instead of private inheritance is not as convenient as private inheritance. Often that's a lame excuse for being lazy.
I don't think anyone knows what protected inheritance models. At least I haven't seen any convincing explanation yet.
If you inherit publicly from another class, everybody knows you are inheriting and you can be used polymorphically by anyone through a base class pointer.
If you inherit protectedly only your children classes will be able to use you polymorphically.
If you inherit privately only yourself will be able to execute parent class methods.
Which basically symbolizes the knowledge the rest of the classes have about your relationship with your parent class
Accessors | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public | y | y | y
—————————————+————————————+———————————————+———————
protected | y | y | n
—————————————+————————————+———————————————+———————
private | | |
or | y | n | n
no accessor | | |
y: accessible
n: not accessible
Based on this example for java... I think a little table worth a thousand words :)
Protected data members can be accessed by any classes that inherit from your class. Private data members, however, cannot. Let's say we have the following:
class MyClass {
private:
int myPrivateMember; // lol
protected:
int myProtectedMember;
};
From within your extension to this class, referencing this.myPrivateMember won't work. However, this.myProtectedMember will. The value is still encapsulated, so if we have an instantiation of this class called myObj, then myObj.myProtectedMember won't work, so it is similar in function to a private data member.
Summary:
Private: no one can see it except for within the class
Protected: Private + derived classes can see it
Public: the world can see it
When inheriting, you can (in some languages) change the protection type of a data member in certain direction, e.g. from protected to public.
Private:
The private members of a base class can only be accessed by members of that base class .
Public:
The public members of a base class can be accessed by members of that base class, members of its derived class as well as the members which are outside the base class and derived class.
Protected:
The protected members of a base class can be accessed by members of base class as well as members of its derived class.
In short:
private: base
protected: base + derived
public: base + derived + any other member
I have tried explaining inheritance using a picture below.
The main gist is that the private members of parent class are never directly accessible from derived/child class but you can use parent class's member function to access the private members of parent class.
Private variables are always present in derived class but it cannot be accessed by derived class. Its like its their but you cannot see with your own eyes but if you ask someone form the parent class then he can describe it to you.
I found an easy answer and so thought of posting it for my future reference too.
Its from the links http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
It's essentially the access protection of the public and protected members of the base class in the derived class. With public inheritance, the derived class can see public and protected members of the base. With private inheritance, it can't. With protected, the derived class and any classes derived from that can see them.
What is the difference between public, private, and protected inheritance in C++?
All of the questions I've found on SO deal with specific cases.
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A // 'private' is default for classes
{
// x is private
// y is private
// z is not accessible from D
};
IMPORTANT NOTE: Classes B, C and D all contain the variables x, y and z. It is just question of access.
About usage of protected and private inheritance you could read here.
To answer that question, I'd like to describe member's accessors first in my own words. If you already know this, skip to the heading "next:".
There are three accessors that I'm aware of: public, protected and private.
Let:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
Everything that is aware of Base is also aware that Base contains publicMember.
Only the children (and their children) are aware that Base contains protectedMember.
No one but Base is aware of privateMember.
By "is aware of", I mean "acknowledge the existence of, and thus be able to access".
next:
The same happens with public, private and protected inheritance. Let's consider a class Base and a class Child that inherits from Base.
If the inheritance is public, everything that is aware of Base and Child is also aware that Child inherits from Base.
If the inheritance is protected, only Child, and its children, are aware that they inherit from Base.
If the inheritance is private, no one other than Child is aware of the inheritance.
Limiting the visibility of inheritance will make code not able to see that some class inherits another class: Implicit conversions from the derived to the base won't work, and static_cast from the base to the derived won't work either.
Only members/friends of a class can see private inheritance, and only members/friends and derived classes can see protected inheritance.
public inheritance
IS-A inheritance. A button is-a window, and anywhere where a window is needed, a button can be passed too.
class button : public window { };
protected inheritance
Protected implemented-in-terms-of. Rarely useful. Used in boost::compressed_pair to derive from empty classes and save memory using empty base class optimization (example below doesn't use template to keep being at the point):
struct empty_pair_impl : protected empty_class_1
{ non_empty_class_2 second; };
struct pair : private empty_pair_impl {
non_empty_class_2 &second() {
return this->second;
}
empty_class_1 &first() {
return *this; // notice we return *this!
}
};
private inheritance
Implemented-in-terms-of. The usage of the base class is only for implementing the derived class. Useful with traits and if size matters (empty traits that only contain functions will make use of the empty base class optimization). Often containment is the better solution, though. The size for strings is critical, so it's an often seen usage here
template<typename StorageModel>
struct string : private StorageModel {
public:
void realloc() {
// uses inherited function
StorageModel::realloc();
}
};
public member
Aggregate
class pair {
public:
First first;
Second second;
};
Accessors
class window {
public:
int getWidth() const;
};
protected member
Providing enhanced access for derived classes
class stack {
protected:
vector<element> c;
};
class window {
protected:
void registerClass(window_descriptor w);
};
private member
Keep implementation details
class window {
private:
int width;
};
Note that C-style casts purposely allows casting a derived class to a protected or private base class in a defined and safe manner and to cast into the other direction too. This should be avoided at all costs, because it can make code dependent on implementation details - but if necessary, you can make use of this technique.
These three keywords are also used in a completely different context to specify the visibility inheritance model.
This table gathers all of the possible combinations of the component declaration and inheritance model presenting the resulting access to the components when the subclass is completely defined.
The table above is interpreted in the following way (take a look at the first row):
if a component is declared as public and its class is inherited as public the resulting access is public.
An example:
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
The resulting access for variables p, q, r in class Subsub is none.
Another example:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
The resulting access for variables y, z in class Sub is protected and for variable x is none.
A more detailed example:
class Super {
private:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
int main(void) {
Super object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Now lets define a subclass:
class Sub : Super { };
int main(void) {
Sub object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
The defined class named Sub which is a subclass of class named Super or that Sub class is derived from the Super class.
The Sub class introduces neither new variables nor new functions. Does it mean that any object of the Sub class inherits all the traits after the Super class being in fact a copy of a Super class’ objects?
No. It doesn’t.
If we compile the following code, we will get nothing but compilation errors saying that put and get methods are inaccessible. Why?
When we omit the visibility specifier, the compiler assumes that we are going to apply the so-called private inheritance. It means that all public superclass components turn into private access, private superclass components won't be accessible at all. It consequently means that you are not allowed to use the latter inside the subclass.
We have to inform the compiler that we want to preserve the previously used access policy.
class Sub : public Super { };
Don’t be misled: it doesn’t mean that private components of the Super
class (like the storage variable) will turn into public ones in a
somewhat magical way. Private components will remain private, public
will remain public.
Objects of the Sub class may do "almost" the same things as their older siblings created from the Super class. "Almost" because the fact of being a subclass also means that the class lost access to the private components of the superclass. We cannot write a member function of the Sub class which would be able to directly manipulate the storage variable.
This is a very serious restriction. Is there any workaround?
Yes.
The third access level is called protected. The keyword protected means that the component marked with it behaves like a public one when used by any of the subclasses and looks like a private one to the rest of the world. -- This is true only for the publicly inherited classes (like the Super class in our example) --
class Super {
protected:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
class Sub : public Super {
public:
void print(void) {cout << "storage = " << storage;}
};
int main(void) {
Sub object;
object.put(100);
object.put(object.get() + 1);
object.print();
return 0;
}
As you see in the example code we a new functionality to the Sub class and it does one important thing: it accesses the storage variable from the Super class.
It wouldn’t be possible if the variable was declared as private.
In the main function scope the variable remains hidden anyway so if you write anything like:
object.storage = 0;
The compiler will inform you that it is an error: 'int Super::storage' is protected.
Finally, the last program will produce the following output:
storage = 101
It has to do with how the public members of the base class are exposed from the derived class.
public -> base class's public members will be public (usually the default)
protected -> base class's public members will be protected
private -> base class's public members will be private
As litb points out, public inheritance is traditional inheritance that you'll see in most programming languages. That is it models an "IS-A" relationship. Private inheritance, something AFAIK peculiar to C++, is an "IMPLEMENTED IN TERMS OF" relationship. That is you want to use the public interface in the derived class, but don't want the user of the derived class to have access to that interface. Many argue that in this case you should aggregate the base class, that is instead of having the base class as a private base, make in a member of derived in order to reuse base class's functionality.
Member in base class : Private Protected Public
Inheritance type : Object inherited as:
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
1) Public Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected members of Base class remain protected in Derived class.
c. Public members of Base class remain public in Derived class.
So, other classes can use public members of Base class through Derived class object.
2) Protected Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected members of Base class remain protected in Derived class.
c. Public members of Base class too become protected members of Derived class.
So, other classes can't use public members of Base class through Derived class object; but they are available to subclass of Derived.
3) Private Inheritance:
a. Private members of Base class are not accessible in Derived class.
b. Protected & public members of Base class become private members of Derived class.
So, no members of Base class can be accessed by other classes through Derived class object as they are private in Derived class. So, even subclass of Derived
class can't access them.
Public inheritance models an IS-A relationship. With
class B {};
class D : public B {};
every D is a B.
Private inheritance models an IS-IMPLEMENTED-USING relationship (or whatever that's called). With
class B {};
class D : private B {};
a D is not a B, but every D uses its B in its implementation. Private inheritance can always be eliminated by using containment instead:
class B {};
class D {
private:
B b_;
};
This D, too, can be implemented using B, in this case using its b_. Containment is a less tight coupling between types than inheritance, so in general it should be preferred. Sometimes using containment instead of private inheritance is not as convenient as private inheritance. Often that's a lame excuse for being lazy.
I don't think anyone knows what protected inheritance models. At least I haven't seen any convincing explanation yet.
If you inherit publicly from another class, everybody knows you are inheriting and you can be used polymorphically by anyone through a base class pointer.
If you inherit protectedly only your children classes will be able to use you polymorphically.
If you inherit privately only yourself will be able to execute parent class methods.
Which basically symbolizes the knowledge the rest of the classes have about your relationship with your parent class
Accessors | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public | y | y | y
—————————————+————————————+———————————————+———————
protected | y | y | n
—————————————+————————————+———————————————+———————
private | | |
or | y | n | n
no accessor | | |
y: accessible
n: not accessible
Based on this example for java... I think a little table worth a thousand words :)
Protected data members can be accessed by any classes that inherit from your class. Private data members, however, cannot. Let's say we have the following:
class MyClass {
private:
int myPrivateMember; // lol
protected:
int myProtectedMember;
};
From within your extension to this class, referencing this.myPrivateMember won't work. However, this.myProtectedMember will. The value is still encapsulated, so if we have an instantiation of this class called myObj, then myObj.myProtectedMember won't work, so it is similar in function to a private data member.
Summary:
Private: no one can see it except for within the class
Protected: Private + derived classes can see it
Public: the world can see it
When inheriting, you can (in some languages) change the protection type of a data member in certain direction, e.g. from protected to public.
Private:
The private members of a base class can only be accessed by members of that base class .
Public:
The public members of a base class can be accessed by members of that base class, members of its derived class as well as the members which are outside the base class and derived class.
Protected:
The protected members of a base class can be accessed by members of base class as well as members of its derived class.
In short:
private: base
protected: base + derived
public: base + derived + any other member
I have tried explaining inheritance using a picture below.
The main gist is that the private members of parent class are never directly accessible from derived/child class but you can use parent class's member function to access the private members of parent class.
Private variables are always present in derived class but it cannot be accessed by derived class. Its like its their but you cannot see with your own eyes but if you ask someone form the parent class then he can describe it to you.
I found an easy answer and so thought of posting it for my future reference too.
Its from the links http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
It's essentially the access protection of the public and protected members of the base class in the derived class. With public inheritance, the derived class can see public and protected members of the base. With private inheritance, it can't. With protected, the derived class and any classes derived from that can see them.
The question is that I have multiple specialized base classes to be used by clients to develop the derived classes at clients' end. The multiple specialized base classes are all derived from the same base class. So the derived classes by clients are derived from the same base class, and the same base class pointer can be used to point all client classes. My question is how can I hide the private members and methods of base and specialized base classes from clients, and still allows the client to develop derived classes from the same base class? The very simplified codes are as follows:
In Base.h. This is the single common base of all the following specialized base classes.
class Base {
public:
Base() {}
~Base() {}
void Start();
private:
// methods to override by derived class
virtual void DoExecute() {}
private:
void Execute() {
// Do something here
DoExecute();
// Do something here
}
// Other private methods and members
}
In Base.cpp
void Base::Start() {
Execute();
}
In SpecializedBase1.h. One specialized base class for clients to derived special client class.
class SpecializedBase1 : public Base {
public:
SpecializedBase1();
~SpecializedBase1();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
In SpecializedBase2.h. Another specialized base class for clients to derived special client class.
class SpecializedBase2 : public Base {
public:
SpecializedBase2();
~SpecializedBase2();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
In clients' end, two classes are derived to be called by us.
class ClientClass1 : public SpecializedBase1 {
public:
ClientClass1();
~ClientClass1();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
class ClientClass2 : public SpecializedBase2 {
public:
ClientClass2();
~ClientClass2();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
In our end
void Main() {
typedef std::shared_ptr<Base> BasePtr;
std::vector<BasePtr> vec;
// Assume client derived classes creators are available.
vec.push_back(BasePtr(new ClientClass1()));
vec.push_back(BasePtr(new ClientClass2()));
for (auto& step : vec) {
step->Start();
}
}
BTW, this is very simplied verison. Please don't question why we have multiple specialized base classes instead of using the same base class and use pimpl, at this point, it is not possible.
A partial solution: If
you only need hidden private functions (no member variables)
and it is acceptable to make all visible members these functions need to access public
then you could provide these hidden "members" outside the class as non-members, with an explicit pointer to the object. These function can be implemented in the corresponding *.cpp files without being mentioned in the declaration, using static internal linkage or in anonymous namespace, and become completely invisible to clients.
The idea breaks, as soon as you also have private data to hide. The reason is object allocation on the stack. In that case it is the client's responsibility to provide the required memory, which therefore needs to know the object's memory layout including all private members. Impossible, if you hide them. To accomplish this, your would need heap allocation in the constructor, which boils down to PIMPL.
I thought of using protected constructor, but it couldn't completely solve the purpose since the class inheriting from it would be able to instantiate the base class.
As for private constructor, the derived classes too would not be instantiated.
So, any suitable technique would be appreciated.
It is unclear what you are really asking for. So let me try to clear some points:
Pure virtual functions can have definitions
If your concern is that you want to provide definitions for all of the virtual functions in your base you can provide the definitions for the pure virtual functions, and they will be available for static dispatch.
Protected grants access to your base subobject, not to every instance of base
There is a common misconception that protected allows a particular derived type accessing any instance of base. That is not true. The keyword protected grants access to the base subobject within the derived type.
class base {
protected: base() {}
};
class derived : public base {
derived() : base() { // fine our subobject
base b; // error, `b` is not your subobject
}
};
The definition of an abstract class is one that has at least one pure virtual function (virtual function-signature = 0; You can't create an abstract class without them.
Can an abstract class be implemented without pure virtual functions in C++?
If you choose the point of view from Static Polymorphism, you can do that!
An abstract base class would be simply missing a default method implementation for an interface method from the deriving class.
Additionally you can use protected constructors for those CRTP base class templates, to require inheritance for instantiation.
UPDATE:
I found a nice slide show, that explains static vs dynamic polymorphism comprehensively. Each technique has it's pros and cons and certain fields of usage, additionally you can mix both techniques (wisely of course).
To elaborate a bit, I'll give a sample:
template<class Derived>
class AbstractBase
{
public:
// Equivalent for a pure virtual function
void foo()
{
// static_cast<> enforces an 'Is a' relation from Derived to AbstractBase
static_cast<Derived*>(this)->fooImpl();
}
// Equivalent for simple virtual function (overidable from Derived)
void bar()
{
static_cast<Derived*>(this)->barImpl();
}
// Default implementation for any call to bar()
void barImpl()
{
}
protected:
AbstractBase() {}
};
// Compilation will fail, since ConcreteClass1 doesn't provide
// a declaration for fooImpl()
class ConcreteClass1
: public AbstractBase<ConcreteClass1>
{
}
// Compiles fine
class ConcreteClass2
: public AbstractBase<ConcreteClass2>
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
The following sample shows that the pattern introduced above enforces an 'Is a' relationship between abstract class and inheriting class (the template parameter)
class ConcreteClass3
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
// Instantiation will fail, because
// * the constructor is protected
// * at least the static cast will fail
AbstractBase<ConcreteClass3> instance;
I read it in my book
An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration.
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.