C++学习之:组合与继承

1.组合

组合就是把用户定义类的对象作为新类的数据成员 ,大多数对象成员不能像内置类型一样直接赋值,所以不能再构造函数体中通过赋值对用户自定义类型数据成员进行初始化,必须用初始化列表去初始化对象成员,不能在构造函数中赋初值。

class Complex
{
    friend  Complex  operator+(const  Complex  &x, const  Complex  &y);
    friend  istream& operator>>(istream  &is,  Complex  &obj);
    friend  ostream& operator<<(ostream &os, const Complex &obj);
    Rational real;  //实部
    Rational imag;  //虚部
public:
    Complex(int r1 = 0, int r2 = 1, int i1= 0, int i2 = 1):
                                                 real(r1, r2), imag(i1, i2) {}
}; 

2.继承

继承是允许在已有类的基础上创建新的类,在已有类型的基础上加以扩展,形参功能更加强大的类,原有的类叫做基类或父类。新生成的类叫做子类或派生类,派生类也可能会成为未来派生类的基类。
派生类的定义:

class 派生类名:派生方法  基类名
   {
       //派生类新增的数据成员和成员函数
   };

派生方法:

  • 公有派生: public
  • 私有派生:private
  • 保护派生:protected
    比如:
//base类
class base 
{
     int x;
   public: 
     void setx(int k);
}
//derivedl类继承自base类
class derived1: public base {
      int y;
   public: 
      void sety(int k);
} 

派生类的成员函数不能访问基类的私有数据成员
类的每个成员都有访问特性。公有成员能够被程序中所有的函数访问,私有成员只能被自己的成员函数和友元访问。派生类是从基类派生的,但它和基类是两个完全独立的类,因此派生类的成员函数是不能访问基类的私有成员。有了继承,引入了第三种访问特性protected。protected访问特性介于public访问和private访问之间。通常继承时采用的是public继承,它可以在派生类中保持基类的访问特性。另外两种派生方法很少使用。protected成员是一类特殊的私有成员,它不可以被全局函数或其他类的成员函数访问,但能被派生类的成员函数访问
这里写图片描述

派生类初始化操作

派生类继承了其基类的成员,所以在建立派生类的实例对象时,必须初始化基类继承的数据成员。派生类对象析构时,也必须析构基类对象。

派生类不继承基类的构造函数、析构函数和赋值运算符,但是派生类的构造函数、析构函数能调用基类的构造函数、析构函数和赋值运算符。

因为基类的数据成员往往是私有的,派生类的成员函数没有权利访问这些基类的私有数据成员,派生类的构造函数也不例外,也是没有权限访问基类的私有数据成员的。
C++规定,派生类对象的初始化由基类和派生类共同完成。派生类的构造函数体只负责初始化派生类中新增加的新数据成员,派生类在初始化列表调用基类的构造函数初始化基类的数据成员,派生类构造函数也可以隐式调用基类缺省的构造函数。派生类构造函数的一般形式为:

派生类构造函数名(参数表):基类构造函数名(参数表)
     {
      ……
      }

其中基类构造函数中的参数值通常来源于派生类构造函数的参数值,但也可以是常量值。

构造派生类对象时,先执行基类的构造函数,再执行派生类的构造函数。如果派生类新增的数据成员中含有对象成员,则在创建对象时,先执行基类的构造函数,再执行成员对象的构造函数,最后执行自己的构造函数体。

若基类使用缺省或不带参数的构造函数,则在派生类定义构造函数是可略去:基类构造函数名(参数表)。此时若派生类也不需要构造函数,则可不定义构造函数。

当基类构造函数需要参数,而派生类本身并不需要构造函数时,派生类还必须定义构造函数。该函数只是起了一个参数传递作用。

派生类的析构函数值析构自己新增的数据成员,基类成员的析构由基类的析构函数析构

派生类析构函数会自动调用基类的析构函数
派生类对象析构时,先执行派生类的析构函数,再执行基类的析构函数

重定义基类的函数

当派生类对基类的某个功能进行扩展时,他定义的成员函数名可能会和基类的成员函数名重复。如果只是函数名相同,而原型不同时,系统认为派生类中有两个重载函数。如果原型完全相同,则派生类的函数会覆盖基类的函数。这称为重定义基类的成员函数。基类的那个一摸一样的函数派生类对象就看不见了,被派生类的函数覆盖了
如果想调用基类的那个函数可以使用基类名:函数名();

猜你喜欢

转载自blog.csdn.net/wu_qz/article/details/80424629