热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

C++面向对象三大特征(封装、继承、多态)

C面向对象的三大特征:封装、继承、多态C认为万事万物结为对象,对象上有其属性和行为一、封装意义:①将属性和行为作为一个整体,

C++面向对象的三大特征:封装继承多态

C++认为万事万物结为对象,对象上有其属性和行为




一、封装

       意义:①将属性和行为作为一个整体,表现生活中的事物

                  ②将属性和行为加以权限控制

        语法class  类名  {  访问权限: 属性 / 行为 }

       权限公共权限 public      类内可以访问,类外可以访问

                  保护权限 protected 类内可以访问,类外不可以访问(子可以访问父)

                  私有权限 private    类内可以访问,类外不可以访问(子不可以访问父)

       struct 和 class 区别struct默认权限是public ;class默认权限是private 

       成员属性设置为私有: ① 可以自己控制读写权限

                                          ② 对于写可以检测数据的有效性

Class Student()
{
public: //公共权限 类内可以访问,类外可以访问//行为void showStudent(){cout <<"姓名:" <};

            对象的初始化和清理是非常重要的安全问题:

            一个对象或者变量没有初始状态,对其使用后果是未知的

            同样的使用完一个对象或变量,没有及时清理,也会造成一定安全问题

            构造函数析构函数可以解决以上问题,如果我们不提供构造和析构函数,编译器会提供空实现的对应函数


        1.1 构造函数:

                主要作用在创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。

                 语法:类名(){}

                         ① 构造函数,没有返回值也不写void

                         ② 函数名称与类名相同

                         ③ 构造函数可以有参数,可以重载

                         ④ 程序在调用对象时自动调用构造,无须手动调用

                  构造函数分类:

                           按照参数分:有参构造无参构造

                           按照类型分:普通构造拷贝构造

                    构造函数调用: 括号法   显示法   隐式转换法

                    拷贝构造函数的调用:

                         ① 使用一个已经创建完毕的对象来初始化一个新对象

                         ② 值传递的方式给函数参数传值

                         ③ 值方式返回局部对象

                    深拷贝:简单赋值拷贝操作

                    浅拷贝:在堆区重新申请空间,进行拷贝操作  (系统默认 浅拷贝)

                    注意:如果属性有堆开辟的,一定要自己提供拷贝构造函数,防止浅拷贝问题

                    构造函数调用规则:

                          默认情况下,C++编译器至少会给一个类添加3个函数

                          ① 默认构造函数(无参,函数体为空)

                          ② 默认析构函数(无参,函数体为空)

                          ③ 默认拷贝构造函数,对属性进行值拷贝

                          如果用户定义有参构造函数,C++不再提供默认无参构造函数,但会一个默认拷贝构造

                          如果用户定义拷贝构造函数,C++不再提供其他构造函数

 


        1.2 析构函数:

                  主要作用在对象销毁前系统自动调用,执行一些清理工作。

                   语法:~类名(){}

                  ① 析构函数,没有返回值也不写void

                  ② 函数名称与类名相同,在名称前加符号 ~

                  ③ 构造函数不可以有参数,不可以重载

                  ④ 程序在调用对象时自动调用析构,无须手动调用

class Person()
{
public:Person() //默认构造{ cout <<"默认构造函数调用" <}/拷贝调用
//1.使用一个已经创建完毕的对象来初始化一个新对象
void doWork0()
{Person p1;Person p2(p1);
}
//2.值传递的方式给函数参数传值
void doWork1(Person p)
{
}
//3.值方式返回局部对象
Person doWork2()
{Person p1;return p1;
}
/int main()
{//1.括号法Person p1; //默认构造函数调用 不要加()Person p2(10); //有参构造函数调用Person p3(p2); //拷贝构造函数调用//2.显示法Person pA = Person(10); //默认构造Person pA = Person(p2); //拷贝构造Person(10); //匿名对象 特点:当前执行结束,系统自动回收//不要利用拷贝构造函数 初始化匿名对象,编译器认为Person(pA) === Person pA; 报错//Person(pA); //3.隐式转换法Person p4 = 10; //相对与 Person p4 = Person(10);Person p4 = pA; //拷贝构造system("puase");return 0;
}



二、继承

语法class 子类(派生类):继承方式  父类(基类)

多继承语法:class 子类(派生类):继承方式  父类1(基类),继承方式  父类2(基类)   

              注:多继承父类中同名成员,用作用域区分

       继承方式:公共继承、保护继承、私有继承

       注:父类私有成员属性也被继承了,但被编译器隐藏了,无法访问。

       继承中构造和析构顺序:

                     父构造 =》子构造,子析构 =》父析构

       继承同名成员 / 同名静态成员处理方式 :

                     访问子类同名成员,直接访问;访问父类同名成员,需要加作用域。

class Base
{
public:Base(){m_a = 100}void func();void func(int num);int m_a;static int m_b;};
int Base::m_b = 100;
class Son : public Base
{
public:Base(){m_a = 200}void func();int m_a;static int m_b;
};
int Son ::m_b = 200;int main()
{Son s;cout <<"son m_a:" <}

菱形继承:当菱形继承,两父类拥有相同数据,需要作用域区分。

                   数据只需一份,造成资源浪费;利用虚继承解决菱形继承问题。

虚继承语法:继承前 加关键字virtual 基类变成虚基类

class Animal
{
public:int m_age;
}
class Horse : virtual public Animal
{
public:int m_age;
};
class Donkey: virtual public Animal
{
public:int m_age;
};
class Mule : public Horse ,public Donkey{};int main()
{Mule mule;mule.Horse::m_age = 18;mule.Donkey::m_age = 28;//虚基类指针赋值,结果只有一个cout <<"Horse Age:" <}



三、多态

静态多态函数重载运算符重载属于静态多态,复用函数名

动态多态派生类虚函数实现运行时多态

区别:静态多态函数地址早绑定,编译阶段确定函数地址动态多态函数地址晚绑定,运行时确定函数地址

满足条件:① 有继承关系 ② 子类重写父类中的虚函数

使用条件:父类指针引用指向子类对象。

抽象类特点:无法实例化对象;子类必须重新抽象类中纯虚函数,否则子类也属于抽象类。

虚析构,纯虚析构:解决父类指针释放子类对象;需要具体函数实现。(如果子类中没有堆区数据,可不写为虚析构后纯虚析构)

//抽象类
class Animal
{
public:Animal(){};//纯虚析构 利用虚析构解决父类指针释放子类对象时不干净//需要声明,也需要实现virtual ~Animal() = 0;//纯虚函数 虚函数指针,占四字节virtual void speak() = 0;
};//纯虚析构实现
Animal::~Animal()
{cout <<"Animal 纯虚析构" <}class Cat :public Animal
{
public: Cat(string name){m_strName = new String(name);}~Cat(){if(m_strName != NULL){delete m_strName;m_strName = NULL;}}//重写 函数返回值类型 函数名 参数列表完全相同speak(){cout <<"Cat Speak" <};void doSpeak(const Animal &animal)
{animal.speak();
}int main()
{/*重写虚函数,执行子类函数;若不使用虚函数,执行则问父类函数;*/Cat cat;doSpeak(cat);system("puase");return 0;
}

 


推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 如何在跨函数中使用内存?
    本文介绍了在跨函数中使用内存的方法,包括使用指针变量、动态分配内存和静态分配内存的区别。通过示例代码说明了如何正确地在不同函数中使用内存,并提醒程序员在使用动态分配内存时要手动释放内存,以防止内存泄漏。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 设计模式——模板方法模式的应用和优缺点
    本文介绍了设计模式中的模板方法模式,包括其定义、应用、优点、缺点和使用场景。模板方法模式是一种基于继承的代码复用技术,通过将复杂流程的实现步骤封装在基本方法中,并在抽象父类中定义模板方法的执行次序,子类可以覆盖某些步骤,实现相同的算法框架的不同功能。该模式在软件开发中具有广泛的应用价值。 ... [详细]
  • Iamtryingtocreateanarrayofstructinstanceslikethis:我试图创建一个这样的struct实例数组:letinstallers: ... [详细]
  • 本文介绍了一种图的存储和遍历方法——链式前向星法,该方法在存储带边权的图时时间效率比vector略高且节省空间。然而,链式前向星法存图的最大问题是对一个点的出边进行排序去重不容易,但在平行边无所谓的情况下选择这个方法是非常明智的。文章还提及了图中搜索树的父子关系一般不是很重要,同时给出了相应的代码示例。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
author-avatar
wwwmanbj_796_897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有