Inheritance related knowledge:
Private inheritance is not visible to derived classes (exist but not accessable)
private and protect inheritance does not allow a base class pointer to point to a derived class (compilederror: ‘BaseClass‘ is an inaccessible base of ‘DerivedClass‘
- Reinterpret_cast can force a derived class pointer of private inheritance into a pointer to a base class (pass
pbase = static_cast <BaseClass*>(pdrived)
; but don't do it because it violates the Pravite inheritance principle!) (dynamic_cast not, some people say static_cast can also, but I tried not: gcc4.8.1,c++1)
Pravite inheritance is similar to (similar, differentiated) the addition of a private member variable (composition) in the base class respecting the original, the original link:
//e.g., the "Car has-a Engine" Relationship can be expressed using simple compositionClass Engine { Public:Engine(intNumcylinders);voidStart ();//starts this Engine};class Car { Public:Car() :E_(8) {}//Initializes this Car with 8 cylinders voidStart () {E_.start ();}//Start This Car by starting its EnginePrivate: Engine e_;//Car has-a Engine};//the "Car has-a Engine" Relationship can also be expressed using private inheritance:Class Car:PrivateEngine {//Car has-a Engine Public:Car() :Engine(8) {}//Initializes this Car with 8 cylinders usingEngine::start;//Start This Car by starting its Engine};//Use composition or private inheritance?//use composition When can, private inheritance//"Isa" relationship should is modelled by inheritance, "Has-a" should is modelled by containment:Class B: PublicA//B " is-a "a {...} class B {...Private: A A_;//B "Has-a" a}//while Public inheritence Model A "is-a" relationship, private inheritance doesn ' t model anything at all, and is pur Ely an implementation construct for sharing code with the class being inherited. This was better achieved by containment.
There is several similarities between these-variants:
In both cases there are exactly one Engine member object contained in every Car object
In neither case can users (outsiders) convert a car* to an engine*
In both cases the Car class have a start () method that calls the >start () method on the contained Engine object.
There is also several distinctions:
The Simple-composition variant is needed if you want to contain several Engines per Car
The Private-inheritance variant can introduce unnecessary multiple inheritance
The Private-inheritance variant allows members of Car to convert a car* to an engine*
The Private-inheritance variant allows access to the protected members of the base class
The Private-inheritance variant allows Car to override Engine ' s virtual functions
The Private-inheritance variant makes it slightly simpler (characters compared to + characters) to give Car a start () method that simply calls through to the Engine's start () method
Note thatprivate inheritance is usually used to gain access into the protected members of the base class, but it is usually a short-term solution.
-Or a member (either data member Or member function) declared in a protected sections of a class can only being accessed by M Ember functions and friends of that class, and by member functions and friends ofDerived Classes, which is why private inheritance can access the base class members of protected.
&OJB = this pointer in class, derived class pointer to base class pointer example: Original link
classAnimal {/ * Some Virtual Members * /}classDog: PublicAnimal {};classCat: PublicAnimal {};D og Dog; Cat Cat; animal& AnimalRef1 = dog;//Notice no cast required. (Dogs and cats are animals).animal& AnimalRef2 = cat; animal* ANIMALPTR1 = &dog; animal* ANIMLAPTR2 = &cat; cat& CATREF1 =dynamic_cast<Cat&> (ANIMALREF1);//Throws An exception AnimalRef1 is a dogcat* CATPTR1 =dynamic_cast<Cat*> (ANIMALPTR1);//Returns NULL AnimalPtr1 is a dogcat& CatRef2 =dynamic_cast<Cat&> (ANIMALRED2);//Workscat* CATPTR2 =dynamic_cast<Cat*> (ANIMALPTR2);//Workshand makes no sense//An animal object was not a cat. Therefore It can is treated like a Cat.Animal A; cat& CATREF1 =dynamic_cast<Cat&> (a);//Throws An exception it not a CATcat* CATPTR1 =dynamic_cast<Cat*> (&a);//Returns NULL its not a CAT.
In most cases, if you need to use an inherited property, you define the data as private and provide a protected interface so that derived classes can define their own private data and do not conflict with the data of the base class, and can access the data of the base class, and more importantly, In the future you will need to modify the base class data members without making the derived class error, which maximizes code reuse (as long as the protected interface is not changed). If your code is less, but you need to use an inherited attribute, you can define a small amount of protected data, which eliminates the requirement to define a bunch of interfaces and simplify the code.
Key points:
Virtual destructor: The destructor of the base class must be a virtual function to prevent a memory leak (slicing)--make your destructor virtual If your class have any virtual functions (as long as there is a virtual letter Number). Had Base ' s destructor not been virtual, Derived ' s destructor would not having been called–with likely bad effects, such as Resources owned by Derived not being freed.
When designing a function pass-by-value should be avoided for objects:
myMethod (const SomeClass &object) // goodobject) // bad: don‘t do this
- Efficiency issues
- Objects passed by value through a Base-class variable would in effect behave as a Base-class object without the extended in Formation defined by the derived class, if the argument is a base class, the derived classes are truncated.
Interface: A class with no data and where all functions is pure virtual functions (generally public) is often called an interface.
the implementation of pure virtual functions derived classes must redefine pure virtual functions, but some common code can be implemented in pure virtual functions, for example, you can use to perform some of the common default settings, explicitly execute BaseClass in a derived class::p Ure_virtual_ func; The default setting can also be done by defining the protected member function in the base class and then deriving to be able to call the protected function of the base class in its member function.
Derived classes call base class functions
void Der::f(){ Base::f(); // Or, if you prefer, this->Base::f();}
Virtual Constructor? is the clone (copy) and create (construct) of the pure virtual function, but the pointer to the derived class is returned in the derivation, not the base class pointer. That's how to define a copy constructor or assignment operator for a class that contains a pointer to a (abstract) base CL The:
Class Shape { Public:Virtual~Shape() { }//A virtual destructor Virtual voidDraw () =0;//A pure virtual function Virtual voidMove () =0;// ... Virtualshape* Clone ()Const=0;//Uses the copy constructor Virtualshape* Create ()Const=0;//Uses The default constructor};class Circle: PublicShape { Public: circle*Clone()Const;//covariant Return Types; see belowcircle* Create ()Const;//covariant Return Types; see below // ...}; circle* Circle::clone ()Const{return NewCircle (* This); }circle* Circle::create ()Const{return NewCircle (); }
never hide member functions that were public in my base class
C + + can ' t distinguish between a pointer-to-a-thing and a pointer-to-an-array-of-things
class Base {public: virtual void f(); };class Derived : public Base {public: ...private: int i_;};void userCode(Base* arrayOfBase){ arrayOfBase[1].f(); // 此处如果传进来的是派生类,则编译器会按照基类的大小去在数组中找索引为110> 能在编译的时候报错,而不是运行时出错}int main(){ Derived arrayOfDerived[10]; userCode(arrayOfDerived); ...}
To be continued ....
C + + Private inheritance