欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-10-19 19:44:31
c++为什么要有继承 我们都知道很多类都有自己的数据成员以及函数,在编写程序时,会有很多类的拥有相同的数据成员和函数,为了节省时间以及代码量,我们把这些公共的数据和函数封装成一个类,后面的类只要继承...

c++为什么要有继承

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

什么是继承

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

例如:

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

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

继承的访问限定符有:

public / protected /private

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

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

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

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

继承与转换(public继承)

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

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

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

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

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;
};