C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

继承的基本语法: 继承的目的就是用于提高代码的复用性,减少重复代码的开发,提高工作效率,先来定义简单的继承关系.

#include <iostream>

using namespace std;

class BasePage
{
private:
int m_x; protected:
int m_y; public:
void header() { cout << "header" << endl; }
void footer() { cout << "footer" << endl; }
}; // 新建一个News类,以公有属性继承BasePage类中的内容
class News :public BasePage
{
public:
void connect() { cout << "connect" << endl; }
}; int main(int argc, char *argv[])
{
News news;
news.header();
news.footer(); system("pause");
return 0;
}

继承中的构造/析构函数: 继承后的构造顺序base start -> news start析构顺序news end -> base end.

#include <iostream>

using namespace std;

class BasePage
{
public:
BasePage(){ cout << "base page -> start" << endl; }
~BasePage(){ cout << "base page -> end" << endl; }
}; class News :public BasePage
{
public:
News(){ cout << "news page -> start" << endl; }
~News(){ cout << "news page -> end" << endl; }
}; void call()
{ // 此处如果初始化写在main中,将无法看到析构函数的执行
News news;
} int main(int argc, char *argv[])
{
call();
system("pause");
return 0;
}

继承下的同名函数调用: 在继承多个类的时候,难免会出现同名函数的冲突问题,在调用是可以指明其作用域.

#include <iostream>

using namespace std;

class BasePage
{
public:
void func(int x, int y)
{
cout << "BasePage -> " << x + y << endl;
}
}; class News :public BasePage
{
public:
void func(int x, int y)
{
cout << "News -> " << x + y << endl;
}
}; int main(int argc, char *argv[])
{
News news; // 如果想调用父类的func()则需要
news.BasePage::func(10,20); // 调用子类的则是
news.func(100, 200); system("pause");
return 0;
}

继承下的静态成员属性: 静态成员属性也可以直接通过作用域方式直接调用.

#include <iostream>

using namespace std;

class BasePage
{
public:
static int m_x; public:
static void func(int x, int y) {cout << "BasePage -> " << x + y << endl;}
}; class News :public BasePage
{
public:
static int m_x; public:
static void func(int x, int y) {cout << "News -> " << x + y << endl;}
}; int BasePage::m_x = 100;
int News::m_x = 200; int main(int argc, char *argv[])
{
News news; cout << News::m_x << endl;
cout << News::BasePage::m_x << endl; News::func(10,20);
News::BasePage::func(100,200); system("pause");
return 0;
}

多继承的调用: 定义Super派生类,分别继承Base1Base2这两个基类.

#include <iostream>

using namespace std;

class Base1
{
public:
int m_x;
public:
Base1(){ m_x = 10; }
void show() { cout << m_x << endl; }
}; class Base2
{
public:
int m_x;
public:
Base2(){ m_x = 20; }
void show() { cout << m_x << endl; }
}; class Super :public Base1, public Base2
{
public:
int m_y;
public:
Super(){ m_y = 30; }
void display(){ cout << m_y << endl; }
}; int main(int argc, char *argv[])
{
Super super; cout << super.Base1::m_x << endl;
cout << super.Base2::m_x << endl;
cout << super.m_y << endl; super.Base1::show();
super.display(); system("pause");
return 0;
}

菱形继承(虚继承): 虚继承可能会出现多个基类中存在相同的成员数据,从而造成内存开销过大,虚基类即可解决开销问题.

#include <iostream>

using namespace std;

class Animal
{
public:
int m_Age;
}; // 虚基类 Sheep
class Sheep :virtual public Animal { }; // 虚基类 Tuo
class Tuo :virtual public Animal { }; // 定义派生类
class SheepTuo :public Sheep, public Tuo { }; int main(int argc, char *argv[])
{
SheepTuo ptr; ptr.Sheep::m_Age = 10;
ptr.Tuo::m_Age = 20; cout << ptr.Sheep::m_Age << endl;
cout << ptr.Tuo::m_Age << endl;
cout << ptr.m_Age << endl; system("pause");
return 0;
}

虚函数实现动态多态: 动态多态的作用是,通过传递不同的类指针,实现调用不同的方法,同一个结构返回不同的状态.

#include<iostream>

using namespace std;

class Animal
{
public:
virtual void speak() { cout << "Animal speak" << endl; }
virtual void eat() { cout << "Animal eat" << endl; }
}; class Cat :public Animal
{
public:
void speak() { cout << "Cat speak" << endl; }
virtual void eat() { cout << "cat eat" << endl; }
}; class Dog :public Animal
{
public:
void speak() { cout << "Dog speak" << endl; }
virtual void eat() { cout << "dog eat" << endl; }
}; void doSpeak(Animal & animal)
{
animal.speak();
} int main(int argc, char *argv[])
{
Cat cat_ptr;
doSpeak(cat_ptr); // 调用同一个函数,返回不同的结果 Dog dog_ptr;
doSpeak(dog_ptr); system("pause");
return 0;
}

纯虚函数实现多态: 如果父类中存在纯虚函数,子类继承父类后就必须要实现纯虚函数,父类中存在纯虚函数,该类无法实例化对象,只能被继承后实现,这种类也被叫做抽象类.

#include <iostream>

using namespace std;

class AbstractCalculator
{
public:
int x;
int y; public:
// virtual int getResult() { return 0; }; // 定义虚函数
virtual int getResult() = 0; // 定义纯虚函数
void Set_Val(int x, int y){ this->x = x; this->y = y; };
}; class AddCalculator :public AbstractCalculator
{
public:
virtual int getResult() // 扩展getResult方法
{
return x + y;
}
}; class SubCalculator :public AbstractCalculator
{
public:
virtual int getResult()
{
return x - y;
}
}; int main(int argc, char *argv[])
{
AbstractCalculator *ptr = new AddCalculator; // 创建一个加法
ptr->Set_Val(10, 20);
cout << "x+y = " << ptr->getResult() << endl;
delete ptr; ptr = new SubCalculator; // 创建一个减法
ptr->Set_Val(10, 20);
cout << "x-y = " << ptr->getResult() << endl;
delete ptr; system("pause");
return 0;
}

实现虚析构函数: 在基类的析构函数上加上virtual将其修饰为虚析构函数,其解决的问题是父类指针释放子类对象时,无法释放掉子类对象中的数据,或者说无法调用到子类对象的析构函数,我们可以利用虚析构来解决这个问题.

#include <iostream>

using namespace std;

class Animal
{
public:
// 此处加上virtual声明为虚析构函数
virtual ~Animal() { cout << "Animal back" << endl; }
}; class Cat :public Animal
{
public:
char *m_name; public:
Cat(const char *name)
{
this->m_name = new char[strlen(name) + 1];
strcpy(this->m_name, name);
}
~Cat()
{
cout << "Cat back" << endl;
if (this->m_name != NULL)
{
delete[] this->m_name;
this->m_name = NULL;
}
}
}; int main(int argc, char *argv[])
{
Animal *ptr = new Cat("Tomcat");
delete ptr;
system("pause");
return 0;
}

实现纯虚析构函数: 如果函数中出现了纯虚析构函数,那么这个类也算抽象类,不可实例化对象,纯虚析构函数必须要存在实现,并且实现代码必须在类外,因为类内被定义为了纯虚析构函数,所以只能在类外部完成了.

#include <iostream>

using namespace std;

class Animal
{
public:
// 此处加上 virtual 声明为纯虚析构函数
virtual ~Animal() = 0 ;
}; Animal::~Animal()
{
// 纯虚析构函数实现
cout << "Animal back" << endl;
} class Cat :public Animal
{
public:
char *m_name; public:
Cat(const char *name)
{
this->m_name = new char[strlen(name) + 1];
strcpy(this->m_name, name);
}
~Cat()
{
cout << "Cat back" << endl;
if (this->m_name != NULL)
{
delete[] this->m_name;
this->m_name = NULL;
}
}
}; int main(int argc, char *argv[])
{
Animal *ptr = new Cat("Tomcat");
delete ptr;
system("pause");
return 0;
}

8.5 C++ 继承与多态的更多相关文章

  1. Objective-C中的继承和多态

    面向对象编程之所以成为主流的编程思想和他的继承和多态是分不开的,只要是面向对象语言都支持继承和多态,当然不同的OOP语言之间都有其特点.OC中和Java类似,不支持多重继承,但OOP语言C++就支持多 ...

  2. java中抽象、分装、继承和多态的理解

    1.抽象.封装装.继承和多态是java面向对象编程的几大特点. 抽象:所谓抽象就是对某件事务,我们忽略我们不关心不需要的部分,提取我们想要的属性和行为,并且以代码的形式提现出来:例如我们需要对一个学生 ...

  3. [转] JS中简单的继承与多态

    这里讲了一个最最最简单的JS中基于原型链的继承和多态. 先看一下以下这段代码的实现(A是“父类”,B是“子类”): var A = function(){ this.value = 'a'; this ...

  4. 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目

    小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...

  5. OC的封装、继承与多态

    面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐 ...

  6. 2、C#面向对象:封装、继承、多态、String、集合、文件(上)

    面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. ...

  7. Java学习笔记 07 接口、继承与多态

    一.类的继承 继承的好处 >>使整个程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性 继承的基本思想 >>基 ...

  8. JavaScript 面向对象程序设计(下)——继承与多态 【转】

    JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论 ...

  9. Java继承和多态实例

    我们知道面向对象的三大特性是封装.继承和多态.然而我们有时候总是搞不清楚这些概念.下面对这些概念进行整理, 为以后面向抽象的编程打下坚实的基础. 封装的概念还是很容易理解的.如果你会定义类,那么相信你 ...

  10. python基础——继承和多态

    python基础——继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类 ...

随机推荐

  1. Zookeeper面试题总结

    1.请简述Zookeeper的选举机制 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的. 假设这些服务器 ...

  2. AtCoder ABC 165 D - Floor Function (Good, 手动模拟推出公式)

    题目链接:Here 题意: 给出正整数 \(A,B,N (1\le A\le 1e6,1\le B,N\le1e12)\) ,对于 \(x\in [0,N]\) 求出 \(\left\lfloor\f ...

  3. Tomcat 优雅关闭之路

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ZqkmoAR4JEYr0x0Suoq7QQ作者:马运杰 本文通过阅读Tomcat启动和关闭流程 ...

  4. iview 将Modal抽取成组件并控制Modal的显示隐藏

    开发中遇到Modal弹出框的内容太多,就想把Modal单独分装成一个组件,但是发现封装成组件后Modal的关闭和打开有问题.如下方法可以解决这个问题. 父级页面: <PriceInfodModa ...

  5. 一、mysql5.7 rpm 安装(单机)

    一.下载需要的rpm包mysql-community-client-5.7.26-1.el6.x86_64.rpmmysql-community-common-5.7.26-1.el6.x86_64. ...

  6. plsqll连接Oracle的两种方式

    第一种方式:配置tnsnames.ora 找到plsql软件根目录 下的配置文件

  7. Spring boot 运行服务jar外配置配置文件方式总结

    本文为博主原创,转载请注明出处: 由于需要在本地编译打包,在服务器上验证某些功能,需要频繁修改配置,本地打包时,会将配置文件也打包的jar 包内部,这种方式下,若修改配置则需要本地修改重新上传服务器一 ...

  8. zookeeper源码(03)启动流程

    本文将从启动类开始详细分析zookeeper的启动流程: 加载配置的过程 集群启动过程 单机版启动过程 启动类 org.apache.zookeeper.server.quorum.QuorumPee ...

  9. 达梦数据库varchar和nvarchar的验证

    达梦数据库varchar和nvarchar的验证 测试SQL create tablespace zhaobsh datafile '/opt/dmdbms/data/DAMENG/zhaobsh.d ...

  10. [转帖]CENTOS6.5 没有/LIB64/LIBFUSE.SO.2的问题

    yum install fuse-libs