继承(隐藏 & 派生类的六个默认成员函数)

1 隐藏(重定义)
隐藏是指:在基类和派生类中有同名的成员变量或成员函数,那么派生类的成员变量、成员函数就将基类的隐藏(重定义)了。
隐藏(重定义)
如何调用隐藏的成员函数(或使用隐藏的成员变量)?
隐藏——赋值
指定作用域
调用隐藏的成员
2 派生类的六个默认成员函数
在默认情况下,派生类的默认成员函数由基类的成员函数合成(具体实现见下面的代码)
(1)构造函数
子类的构造函数,继承了父类的构造函数,需要先调用父类的构造函数,再构造自己的成员
对于子类中继承而来的父类的成员,一般可以采用匿名对象的方式进行初始化
(2)拷贝构造
对子类的拷贝构造,先将参数t中切片给子类中从父类继承而来的成员,再对子类中自己的成员进行拷贝构造。
子类的拷贝构造
(3)赋值运算符重载
赋值运算符的函数均为operator=,所以明显子类和父类的赋值运算符重载函数的函数名一样,构成隐藏(重定义),在子类中调用父类的赋值运算符重载函数时需要指定作用域。
(4)析构函数
一般析构函数不显示的调用。
虽然子类和父类的函数名不同,但在编译器中会对析构函数进行处理,全部变为函数名为distructor的函数,所以析构函数也构成隐藏(重定义),如果想要调用父类的析构函数,必须指定作用域。
析构函数是先析构子类自己的成员,再调用父类的析构函数

//派生类的六个默认成员函数(以日期类为例)
class Date
{
public:
      Date(int year = 1900,int month = 1,int day = 1)
            :_year(year)
            ,_month(month)
            ,_day(day)
      {}
      Date(const Date& d)
            :_year(d._year)
            ,_month(d._month)
            ,_day(d._day)
      {}
      Date& operator=(const Date& d)
      {
            _year = d._year;
            _month = d._month;
            _day = d._day;
            return *this;
      }
      ~Date()
      {}

private:
      int _year;
      int _month;
      int _day;
};
class Time :public Date
{
public:
      Time(int hour = 0, int minute = 0, int second = 0)
            :Date()               //构造函数:子类中从父类继承的成员,采用匿名对象的方式进行构造
            , _hour(hour)
            , _minute(minute)
            , _second(second)
      {}
      Time(const Time& t)
            :Date(t)            //“切片”
            , _hour(t._hour)
            , _minute(t._minute)
            , _second(t._second)
      {}
      Time& operator=(const Time& t) //与父类的operator构成重定义,需要指定Date的作用域调用operator=
      {
            if (this != &t)
            {
                  Date::operator=(t);
                  _hour = t._hour;
                  _minute = t._minute;
                  _second = t._second;
            }
            return *this;
      }
      ~Time()  //与父类的析构函数也构成重定义,需要指定作用域的调用,但是一般都不需要显示的调用
      {
            Date::~Date();
      }

private:
      int _hour;
      int _minute;
      int _second;
};

3 定义一个不能被继承的类
将构造函数定义为私有的
a.对于父类中私有的成员,不论在哪种继承方式下对于子类而言都是不可见的;
b.子类在构造时,必须先调用父类的构造函数,再构造自己的;
c.不可见的成员是无法调用的,所以该类不能被继承。
d.有一个需要注意的就是:当我们把构造函数定义为私有的,则不能生成该类的实例
e.定义一个静态的公有方法,用于生成该类的实例

//定义一个不能被继承的类
class A
{
public:
      static A* GetInstance()
      {
            return new A();
      }
private:
      A()
      {}
};

int main()
{
      A* pa = A::GetInstance();
      return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39294633/article/details/81083253