频道栏目
首页 > 资讯 > C++ > 正文

关于“C++为什么要有继承?什么是继承?”的探讨

18-06-01        来源:[db:作者]  
收藏   我要投稿

C++为什么要有继承

我们都知道很多类都有自己的数据成员以及函数,在编写程序时,会有很多类的拥有相同的数据成员和函数,为了节省时间以及代码量,我们把这些公共的数据和函数封装成一个类,后面的类只要继承这个类即可。

什么是继承

继承是面向对象复用的重要手段。继承是类型之间的关系建模,共享公有的东西,实现各自本质不同的东西。当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。

例如:

这里写图片描述

1.继承方式和访问限定符的关系

继承的访问限定符有:

public / protected /private

这里写图片描述

三种继承关系下基类成员的在派生类的访问关系变化

这里写图片描述

基类的私有成员在派生类中不能被访问,如果一些基类成员不想被基类帝乡访问,但需要在派生类中访问,就定义为保护成员,可以看出保护成员限定符是因继承才出现的。 public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。 protected/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,是has-a的关系原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。 不管是哪种继承方式,在派生类内部都可以访问基类的公共成员和保护成员,但基类的私有成员存在但是不能访问。 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。 在实际运用中一般使用public继承,极少场景下使用protected/private继承。

继承与转换(public继承)

子类对象可以赋值给父类对象(切割/切片)

这里写图片描述

父类对象不能赋值给子类对象。

父类的指针或引用可以只想子类对象。 子类对象的指针或引用不能指向父类对象

class person
{
public:
 void fun()
 {

 }
protected:
 string _name;
};

class teacher:public person
{
public:
 int _age;
};

int main()
{
 person p;
 teacher t;

 p = t;  //子类对象可以赋值给父类对象。
 //t=p;不允许

 person *p1 = &t;  //父类的指针或引用可以指向子类对象
 person &q1 = t;

 teacher *p2 = (teacher*)&p; //子类的引用或指针不能指向父类对象,(可以强转类型之后完成)
 teacher& q2 = (teacher&)p;
}

在继承体系中基类和派生类都有独立的作用域。

隐藏(重定义):子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问(在子类成员函数中,可以使用 基类::基类成员 访问)

派生了默认成员函数

在继承关系里面,在派生类中如果没有显示定义六个默认成员函数,编译系统则会默认合成这六个成员函数。

当基类构造函数需要外部传递参数才能进行初始化时,派生类必须显式定义构造函数,为基类传递参数;基类如果不需要传递或者可以不传递参数,派生类可以不用显式定义构造函数。

lass person
{
public:
 person(const char* name)  //基类构造函数
  :_name(name)
 {}
 person(const person& p)  //基类拷贝构造
  :_name(p._name)
 {}
 person& operator=(const person& p)  //赋值运算符重载
 {
  if (this != &p)
  {
_name = p._name;
  }
  return *this;
 }
 ~person()//基类析构
 {}

protected:
 const char* _name;
};

class student :public person
{
public:
 student(const char* name, int num)//派生类构造函数
  :person(name)
  , _num(num)
 {}
 student(const student& s)  //派生类拷贝构造
  :person(s)
  , _num(s._num)
 {}

 student & operator=(const student& s) //派生类赋值运算符重载
 {
  if (this != &s)
  {
person::operator=(s);
_num = s._num;
  }
  return *this;
 }
 ~student() //派生类析构
 {}

protected:
 int _num;
};
相关TAG标签
上一篇:Servlet、Jsp学习小总结(jsp 转化流程)
下一篇:Vue初学之简单的组件间传值实现教程
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站