write in advance
this blog, not for record the grammar of C++, but record my thoughts about the reusing code part of C++, which consist of inheritance and multiple inheritance . i found myself hard to dive into the reading of these contents. it takes me such a long time that i am afraid i cannot master it.
when it comes to inheritance, there is access control of public, private and protected. i would like to take about them seperately in three subsections. in addition to the access control, there are also virtual function, pure virtual function, virtual functions pointer(vpt), virtual functions table(vtb), as well as virtual base class. although all are qualified with virtual, vtb, vpt and virtual base class are not virtual exactly.
the reason why vtb, vpr are qualified virtual is that they are here to contain and point to virtual functions seperately. virtual base class, on the other hand, used to settle the problem when a derived class have more than one portion of base class in the condition of multiple inheritance. virtual base class, like virtual functions, also bring some new rules here. but don't worry, it is ok and easy. if u want to master it, of course u need to code and code and code, think and think. after all, it doesn't that scary.
access control part
the default access conrtol of inheritance is private which means when u don't explicitly declare the access control of inheritance, it is private inheritance. and no matter what the inheritance access control is, the private section of the base class remains private in its derived class. the difference between public, protected and private is how the public and protected sections of base class change in the derived class.
public
public inheritance models the is-a relationship, like when u say a studnet is a person, a person can be a base class, and a student derived from it. when it is public inheritance, the public part and protected part of the base class still remain public and protected seperately in the derived class. public part usually consist of methods which can be accessed by the outside world, the so-called interface in other coding language.
private
private inheritance models the has-a relationship. different from public inheritance, the public part and protected part of the base class become private in the derived class. private inheritance inherits the implementaion, not the interface. generally, we put the data in private section, sometimes the helper method is also put here.
protected
it is less likely use than public and private . the difference between it and the private inheritance is that the public part and the protected part of the base class become protected in the derived class. generally, in protected part, u put what u want to be accessed by its derived class. in most situations, they are methods.
use the base class methods in a derived class
C++ gives u option to redefine methods access level in a derived class.(only apply for public or protected portion).
see the code fragment below:
class A
{
private:
int num;
std::string name;
protected:
void Reset();
public:
A() : num(0), name("C++") {}
~A() {};
bool update(int n, std::string str);
};
class B : public A
{
private:
int level;
public:
B() : A(), level(1) {}
~B() {};
A::Reset(); //deprecated
void B_Reset();
protected:
using A::update; //using declaration
};
void B::B_Reset()
{
A::Reset(); // protected access level can be
level = 20; // asscessed by derived class
return;
}
here, u can see the using declaration, deprecated way and u write a new method, in the new method, u use the method the base class has provided.
attention for my commend, the three are the ways u can to redefine access or use the base class's methods.
and remember, u cannot change the privare access control level in a derived class. the use of using only allow u to change between public or protected.
summary
so, like u see, the difference between three access controls is distinguish and easy, just how the public and protected part of the base class become in the derived class. in addition to this, the public models the is-a relationship while private models the has-a relationship. not like them, protected inheritance is much less likely to use, Protected inheritance is used when you want to restrict the use of the base class’s interface to the derived class and its subclasses, often for reasons of encapsulation or to prevent misuse of the base class’s interface. It’s a way to restrict access to the “is-a” relationship.
MI
Multiple inheritance means a derived class derives from more than one base class. there may be some adjustment in coding implementation if the base classes have same name of methods or data. here comes the class qualifier, used to declare which class the method or data belongs to.
virtual base class
virtual base class is a conception in MI, trying to help deal with the problem that occures when a 3-rd generation class derives from 2 immediate class and the 2 immediate classes share a common ancestor. if u do not use the virtual base class, in this situation, u would find u have 2 subobjects of the base class.
in situation like this, if u do not use the virtual base class, the new_class class would have 2 base_base class object, which may be what u want sometimes and not what u want the other times.
if u want the new_class has only 1 subobject of the base_base, u should use the virtual base class.
class immediate_1 : virtual public base_base{};
class immediate_2 : public virtual base_base{};
class new_class : public immediate_1, public immediate_2 {};
in this situation, u make base_base a virtual base class to immediate_1 and immediate_2, so u have only base_base subobject.
chages on constructor
with virtual base class, u need to change how u code the constructors like the following:
new_class(const base_base& bs) : base_base(bs), immediate_1(bs),immediate_2(bs){}
here, we assume that immediate_1 and immediate_2 do not have added data.
that is , u must explicitly invoke the base_base constructor here, then the immediate_1, immediate_2 constructor. u cannot just invoke the immediate constructors and wait for the information passing to the base_base, which is an error.
how to use the method
in this part, what i write down is not coding rules, but suggestions, helping to make your code neater and better organized.
since there may be name ambiguities, u need to qualify the class name before the name of method or data.
in addition to this, u may want to use a modular approach instear of an incremental approach, which means each class, just finish its own part of work. if u want to use the other class method, u can just use the method that class has provided. compared with the incremental approach, it is definitly a better way in most situations.
Dominance
it is a rule here for us to resolve ambiguities, only work if virtual base classes involved,
if a name dominates all others, u can use the name directly without qualifying and it can be used unambiguously.
a name in a derived class dominates the same name in any ancestor class, whether direct or indirect.
the virtual ambiguity rules pay no attention to access rules. even though a method in a immediate class is private and u can't access it, it would still dominates.
there is nothing more to talk about dominance here, as far as i am concerned.
in summary
those above are what i have learnt about the inheritance, i am not that familiar with protected and private. some conceptions here are new to me like 3 weeks ago. hope it would be of help.
added
like private inheritance, containment is another way to model the has-a relationship. i could have a subobject of another class, invoke those methods through the subobject. that is all. since u must be familiar with string class, the containment conception may not be a problem for u.