C++Primer Chapter 13 Class Inheritance

1. The derived class cannot directly access the private members of the base class, it must be done through the base class method. The derived class can directly access (call) the public class methods of the base class.

   When creating a derived class object, the program first creates the base class object. The derived class constructor must use the base class constructor. 

class TablePlayer{ //基类声明,在.h文件中
private: 
  string  firstname;
  string lastname;
public:
  TablePlayer(const string & fn="none", const string & ln="none");
  void Name() const;
};
//方法的实现在.cpp文件中
TablePlayer::TablePlayer(const string & fn, const string & ln) : firstname(fn), 
                         lastname(ln) {}   //成员初始化列表法
void TablePlayer::Name() const
{ std::cout<<lastname<<","<<firstname }   

class ReatedPlayer: public TablePlayer{ //公有派生类
private:
  unsigned int rating;
public:
  ReatedPlayer(unsigned int r, const string & fn="none",
               const string & ln="none") 
  ReatedPlayer(unsigned int r,const TablePlayer & tp); //
  unsigned int Rating() const {return rating; }
};
//派生类的构造函数
ReatedPlayer::ReatedPlayer(unsigned int r, const string & fn,
        const string & ln) : TablePlayer(fn,ln) //将fn,ln参数从派生类构造函数传递到基类构造函数
{
  rating=r;
}

ReatedPlayer::ReatedPlayer(unsigned int r, const string & fn,
        const string & ln) //未调用基类构造函数时,等效于使用默认构造函数  : TablePlayer() 
{
  rating=r;
}

 ReatedPlayer::ReatedPlayer(unsigned int r,const TablePlayer & tp):TablePlayer(tp)
{ 
  rating=r;
}
 ReatedPlayer::ReatedPlayer(unsigned int r,const TablePlayer & tp):
     TablePlayer(tp),rating(r) {} 
int main (void){
 using std::cout; using std::endl;
 TablePlayer player1("Bob", "Boomede");
 RatedPlayer rplayer1(1140, "Mallay","Duck"); //创建派生类对象
 rplayer1.Name(); //派生类可以直接调用基类的公有类方法
}

2. Objects and addresses of derived classes can be assigned to base class references and pointers. But you cannot assign objects and addresses of the base class to derived class references and pointers

 TablePlayer  & rt=rplayer;   TablePlayer  * pt= & rplayer; (合法)

3. Three kinds of inheritance in C++: public inheritance, protected inheritance and private inheritance. Public inheritance (is-a relationship means that the derived class object is also a base class object)

  Inheritance can add attributes to the base class, but cannot delete the base class attributes.

4. The behavior of the same method in the derived class and the base class is different, that is, the behavior of the same method varies with the context. This behavior is called polymorphism.

  •    There are two ways to achieve polymorphic public inheritance: 1) Redefine the base class in the derived class 2) Use virtual methods (precede the keyword virtual when declaring the function).
  •  Declare the redefined methods of the derived class as virtual methods in the base class. (The program will choose the method version based on the object type rather than the reference or pointer type)
  • After a method is declared as a virtual function in the base class, it will automatically become a virtual function in the derived class (virtual can also be added to indicate which are virtual functions).
  • It is also a convention to declare a virtual destructor for the base class. [Make sure to call the destructor in the correct order when releasing the derived class object. Call the derived class destructor first, then call the base class constructor] Analysis: delete pt; When releasing memory, first apply the default destructor of the derived class, release the memory of the derived class object, and then call the virtual destructor in the base class To release memory. If you do not declare the virtual destructor in the base class and directly call the destructor of the base class, only part of the memory will be released, and the memory pointed to by the new class member in the derived class will not be released.
/*基类Brass公有成员函数ViewAcct声明前无virtual*/
 Brass dom(" Dominic Banker",1121,4182.45);//基类对象
 BrassPlus dot("Doroty Banker",1238,2592.00);//派生类对象
 Brass & b1=dom; 
 Brass & b2=dot; //派生类可以直接赋给基类
 b1.ViewAcct(); // 用Brass::ViewAcct() 
 b2.ViewAcct(); // 用Brass::ViewAcct()
/*基类Brass公有成员函数ViewAcct声明前有virtual*/
 b1.ViewAcct(); // 用Brass::ViewAcct() 
 b2.ViewAcct(); // 用BrassPlus::ViewAcct() 根据对象类型而非引用选择版本

5. In the implementation of the member function of the derived class: when calling the public function of the base class, you can directly call such as doubal bal=Balance(), if the virtual function ViewAcct() in the derived class needs to call the virtual function ViewAcct() of the base class, To use scope resolver, it should be written as Brass::ViewAcc()

6. You can use an array to represent multiple types of objects, which is polymorphism.

  Brass * p_client[N]; //Brass[i] pointer can point to Brass object or BrassPlaus object

 p_client[i]=new Brass(temp,tempnum,tempbal); 

 p_client[j]=new BrassPlaus(temp,tempnum,tempbal,tmax,trate); //Satisfy different conditions with corresponding assignment statements

Polymorphism is provided by the following code:

for (int i=0;i<N;i++){   p_client[i]->ViewAcct();   }

 

7. Build in the compilation process, called static build; (you can directly determine which function to compile)

   The compiler must generate the correct virtual function code when the program is running , which is called dynamic binding .

8. Dynamic binding can redefine class methods, and static binding has high efficiency.

9. The way the compiler handles virtual functions:

  •    Add a hidden member to each object. This member holds a pointer to an array of function addresses, which is called a virtual function table ( vtbl: virtual function table,). The virtual function table stores the address of the virtual function declared for the class object. The virtual function address table is an array.
  • [ There is a pointer implicit in the base class object, which points to the address table of all virtual functions in the base class. The derived class object will imply a pointer to the independent address table.          If the derived class provides a new definition of the virtual function, the virtual function table will be saved as a new address, if the derived class does not redefine the virtual function, the vtbl will save the original address of the base class function ]
  • (No matter whether there are 1 or 10 virtual functions in the class, only 1 address member is added to the object, but the size of the table is different)

10. Friends cannot be virtual functions (friends are not class members, only members can be virtual functions)

11. The redefined inheritance method is not overloaded.

  •    The redefined inheritance method should ensure that it is exactly the same as the prototype of the base class. But if there is a return type and the return is a base class reference or pointer, the inheritance method of the derived class is modified to return a reference or pointer to the derived class. class Dwelling {public: virtual Dwelling & build (int n)}; class Hovel:public Dwelling {public: virtual Hovel & build (int n) };
  • If the base class declaration is overloaded, you should redefine all overloaded versions in the derived class. class Dwelling {public: virtual void showperks () const; virtual void showperks (int a) const;}; class Hovel:public Dwelling {public: virtual void showperks () const; virtual void showperks (int a) const; }; 

12. The members of the derived class can directly access the protected members of the base class, but cannot directly access the private members of the base class.

  •        To the outside world, protected members are similar to private members; for derived classes, protected members are similar to public members;
  •        It is best to use private access control for class data members, and do not use protected access control; at the same time, the derived class can access the base class data through the base class method;
  •         For member functions, protection control is useful, allowing derived classes to access internal functions that cannot be used by the public

13. Complex abstract base class (ABC: abstract base class): only defines the interface, not the implementation. At least one pure virtual function interface is used, and classes derived from ABC will use conventional virtual functions to implement this interface according to the specific characteristics of the derived class . To be a true ABC, it must contain at least one pure virtual function. The =0 in the prototype makes the virtual function a pure virtual function.

[When the N class and the M class have certain commonalities, but the M class does not need to completely inherit the data and methods of the N class, you can put the commonality of M and N into ABC, and then derive the N class and M class from ABC . ABC class pointer can manage M class and N class objects at the same time]  Prototype use=0 indicates that the class is an abstract base class. C++ allows pure virtual functions to be defined.

For example: Two classes of ellipse and circle, the common point is the center coordinate method, which is the same as the Move() method, but the Area() is different.

           The Area() method cannot be implemented in ABC. C++ improves unimplemented functions by using pure virtual functions . The end of the pure virtual function declaration is =0 ;

            When a pure virtual function is included in the class declaration, an object of that class should not be created. 

//椭圆和圆的ABC类  
class BaseEllipse{   //声明中含有纯虚函数,不能创建BaseEllipse类对象
  private: 
     double x; //椭圆和圆的共性
     double y;
  public:
     BaesEllipse(double x0=0,double y0=0) :x(x0),y(y0){}
     virtual ~BaesEllipse();
     void Move(int nx,ny) { x=nx; y=ny; } //椭圆和圆的共性
     virtual double Area() const=0; //纯虚函数  椭圆和圆的不同     
}; 

14. Constructor, destructor, assignment function, and friend function cannot be inherited.

 

Guess you like

Origin blog.csdn.net/lvliang2017232003/article/details/88804365