c++--面向对象特性

news2024/11/24 4:46:27

1.面向对象指的是继承,封装,多态。
继承主要关注类的构造,赋值,析构。
以下对多态,封装进行补充说明。

2、多态
2.1.定义
a.赋值
派生类的指针,可以赋值给基类的指针。
派送类的对象,可以赋值给基类的引用。
b.调用
通过基类指针调用基类虚函数时,若派生类提供了派生实现,则调用派生类版本。
通过基类引用调用基类虚函数时,若派送类提供了派送实现,则调用派生类版本。

2.2.最佳实践
基类的析构函数应该定义成虚函数。

#include <iostream>

class Base
{
public:
    Base() {}
    virtual void fun()
    {
        printf("B_fun()\n");
    }

    virtual ~Base()
    {
        printf("~Base()\n");
    }

protected:
    int m_pro;

private:
    int m_pri;
};

class A : public Base
{
public:
    A() : Base() {}

    void fun()
    {
        printf("A_fun()\n");
    }

    ~A()
    {
        printf("~A()\n");
    }
};

int main()
{
    A *pA = new A();
    Base *pB = pA;
    pB->fun();
    delete pB;

    A a;
    Base &b = a;
    b.fun();
    return 0;
}

在这里插入图片描述
2.3.注意点
多态针对类外部使用基类指针或基类引用调用基类虚函数时会发生。
多态针对基类内部调用虚函数,在隐式的this此时关联到派生实例时也会发生。

#include <iostream>

class Base
{
public:
    Base() {}
    virtual void fun()
    {
        printf("B_fun()\n");
    }

    void fun1()
    {
        printf("B_fun1()\n");
        fun();
    }

    virtual ~Base()
    {
        printf("~Base()\n");
    }

protected:
    int m_pro;

private:
    int m_pri;
};

class A : public Base
{
public:
    A() : Base() {}

    void fun()
    {
        printf("A_fun()\n");
    }

    ~A()
    {
        printf("~A()\n");
    }
};

int main()
{
    A *pA = new A();
    Base *pB = pA;
    pB->fun1();
    delete pB;

    A a;
    Base &b = a;
    b.fun1();
    return 0;
}

在这里插入图片描述
3.封装
3.1.访问权限修饰符
a.c++支持的访问权限修饰符有public,protect,private
b.在类型内部,针对类型自身所有成员(不含基类)具有全量(public,protect,private)访问权限。
c.在类型内部,针对类型基类,只能访问基类的public,protect修饰的成员。
c.在类型友元内部,具有等价于类型内部的访问权限。故对类型自身成员有全量访问权限,只能访问基类的public,protect修饰的成员。
d.在类型外部,针对类型自身成员,只对public成员具备访问权限。针对基类成员,只对public继承的基类的public成员具备访问权限。

#include <iostream>

class Base
{
    // 类的友元--全量访问
    friend void friend_fun();
public:
    Base(int i, int j, int k) : m_pub(i), m_pro(j), m_pri(k) {}
    void fun()
    {
        // 类内部访问--全量访问
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, m_pri);
    }

public:
    int m_pub;
protected:
    int m_pro;
private:
    int m_pri;
};

class A1 : public Base
{
    friend void friend_funA1();

public:
    A1(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 公共继承者的内部--只能访问公共基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

// 保护继承
class A2 : protected Base
{
    friend void friend_funA2();
public:
    A2(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 保护继承者的内部--只能访问保护基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

// 私有继承
class A3 : private Base
{
    friend void friend_funA3();

public:
    A3(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 私有继承者的内部--只能访问私有基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

void friend_fun()
{
    // 友元的内部--对类型自身成员全量访问
    Base b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro, b.m_pri);
}

void friend_funA1()
{
    // 友元的内部--对基类,公共基类的public&protect
    A1 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro);
}

void friend_funA2()
{
    // 友元的内部--对基类,保护基类的public&protect
    A2 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro);
}

void friend_funA3()
{
    // 友元的内部----对基类,私有基类的public&protect
    A3 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro, 0);
}

int main()
{
    Base b(11, 22, 33);
    // 类不相干的外部--针对类自身成员,只能访问类自身的public成员。
    b.m_pub;

    A1 a1(2, 3, 4);
    // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    printf("pub_%d,pro_%d,pri_%d\n", a1.m_pub, 0, 0);
     // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    A2 a2(3, 4, 5);
    printf("pub_%d,pro_%d,pri_%d\n", 0, 0, 0);
     // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    A3 a3(4, 5, 6);
    printf("pub_%d,pro_%d,pri_%d\n", 0, 0, 0);
}

理解继承时,对基类的权限修饰。可以认为是指定基类成员被合并到派生类成员时,允许放入的权限区域。
对public继承,允许被放入public,protect,private区域。所以,按基类成员一致权限放入。
对protect继承,允许被放入protect,private区域。所以,基类public,protect成员放入protect区域;private成员放入private区域。
对private继承,允许被放入private区域。所以,基类成员一致放入private区域。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1288171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某60区块链安全之JOP实战二学习记录

区块链安全 文章目录 区块链安全Jump Oriented Programming实战二实验目的掌握对EVM逆向能力实验环境实验工具实验原理实验内容Jump Oriented Programming实战二 实验步骤Jump Oriented Programming实战二 实验目的 学会使用python3的web3模块 学会分析以太坊智能合约中中Jum…

MySQL_1. mysql数据库介绍

shell脚本差不多快完结了接下来会为大家更新MySQL系列的相关的基础知识笔记&#xff0c;希望对大家有所帮助&#xff0c;好废话不多说&#xff0c;接下来开始正题&#xff01; 1.mysql数据库介绍 mysql 是一款安全、跨平台、高效的&#xff0c;并与 PHP、Java 等主流编程语言…

C#,数值计算——计算实对称矩阵所有特征值与特征向量的三角分解与QL迭代法源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Computes all eigenvalues and eigenvectors of a real symmetric matrix by /// reduction to tridiagonal form followed by QL iteration. /// </summary> pu…

Linux磁盘阵列raid

RAID介绍 RAID &#xff08; Redundant Array of Independent Disks &#xff09;即独立磁盘冗余阵列&#xff0c;通常简称为磁盘阵列。简单地说&#xff0c; RAID 是由多个独立的高性能磁盘驱动器组成的磁盘子系统&#xff0c;从而提供比单个磁盘更高的存储性能和数据冗余的技…

使用 javascript 模拟 git diff 命令实现文本文件差异比较

diff.html&#xff1a; <!DOCTYPE html> <html> <head><title>文件比较</title><meta charset"UTF-8"> </head> <body> <h1>文件比较</h1> <form><label for"file1">版本1&…

微服务1 springcloud学习笔记P1-P40

b微服务技术栈_哔哩哔哩_bilibili 文档资料: 链接&#xff1a;https://pan.baidu.com/s/1P_Ag1BYiPaF52EI19A0YRw?pwdd03r 提取码&#xff1a;d03r 一 了解微服务技术 二 Eureka (1) Eureka配置 (2) 注册user-service (3) 总结 Ribbon 负载均衡 (1) 流程 三 nacos配置管理…

CFS三层靶机内网渗透

CFS三层靶机内网渗透 一、靶场搭建1.基础参数信息2.靶场搭建2.1网卡配置2.2Target1配置2.2.1 网卡配置2.2.2 Target1 BT配置 2.3Target2配置2.3.1 网卡配置2.3.2 Target2 BT配置 2.4Target3配置 二、内网渗透Target11.1信息收集1.1.1IP收集1.1.2端口收集1.1.3目录收集 1.2 webs…

思维模型 移情效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。情感迁移&#xff0c;爱屋及乌。 1 移情效应的应用 1.1 移情效应在市场营销中应用-多芬&#xff08;Dove&#xff09;“真美运动” 多芬&#xff08;Dove&#xff09;是一家知名的个人护理…

园区规划技术要点

&#xff08;一&#xff09;技术点介绍 1.WLAN&#xff1a;无线局域网WLAN&#xff08;Wireless Local Area Network&#xff09;是一种无线计算机网络&#xff0c;使用无线信道代替有线传输介质连接两个或多个设备形成一个局域网LAN&#xff08;Local Area Network&#xff09…

BUU UPLOAD COURSE 1

传一个cmd.php木马文件 访问一下这个图片地址 发现什么都没有&#xff0c;在hackbar里面连接一下我们的木马 然后看到了一些目录 然后直接查看flag就出来了 这里也可以用蚁剑去连接 直接访问地址&#xff0c;拿着地址去连接就行了。

从零开始,轻松实现Python接口自动化测试(基于PyCharm)

1.接口清单整理 &#xff08;1&#xff09;请求&#xff1a; 请求URL请求方法请求参数请求报文 &#xff08;2&#xff09;响应 状态码响应数据 2.用例设计 &#xff08;1&#xff09;单接口测试用例 模板&#xff1a;id、模块、接口名称、请求URL、用例名称、请求方法、…

用Python手把手教你WordCloud可视化

目录 WordCloud是什么&#xff1f; 具体使用 总结 WordCloud是什么&#xff1f; WordCloud是一种数据可视化技术&#xff0c;通过根据文本中单词的频率或权重来生成一个视觉上吸引人的词云图。在词云图中&#xff0c;单词的大小和颜色通常与其在文本中的出现频率相关&#…

【Java Web学习笔记】5 - XML

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/xml 零、在线文档 XML系列教程 一、XML引出 1.为什么需要XML 1.需求1 :两个程序间进行数据通信? 2.需求2:给一台服务器&#xff0c;做-一个配置文件&#xff0c;当服务器程序启动时&#xff0c;去…

synxflow 安装环境

介绍&#xff1a; 该软件可以动态模拟洪水淹没&#xff0c;滑坡跳动和泥石流使用多个cuda支持的gpu。它还提供了一个用户友好但多功能的Python界面&#xff0c;可以完全集成到数据科学工作流程中&#xff0c;旨在简化和加速危害风险评估任务。 这个包我从网上找到的资源特别特…

【WPF.NET开发】构造动态布局

本文内容 系统必备创建项目配置默认的 Grid Panel 控件向面板中添加控件测试布局汇总所有内容后续步骤 在动态定位中&#xff0c;您通过指定子元素相对于父元素应该如何排列以及应该如何包装来排列子元素。 您还可以将窗口和控件设置为在其内容扩展时自动扩展。 适用于 Vis…

Avalonia中使用Prism实现区域导航功能

前言 上一篇文章我们讲了在Avalonia开发中&#xff0c;引入Prism框架来完成项目的MVVM迁移。本章内容将带领大家学习如何在Avalonia中使用Prism框架实现区域导航功能。如果你还不知道Avalonia中如何引入Prism框架&#xff0c;请看我上一篇文章&#xff1a;Avalonia框架下面使用…

公有云迁移研究——AWS DMS

大纲 1 什么是DMS2 DMS的作用3 DMS在迁移的时候都做些什么4 在使用DMS的时候我们需要做些什么5 操作5.1 创建两个数据库终端节点5.2 创建迁移任务 6 可能遇到的问题7 总结 在本地机房或其他云往AWS上做迁移时&#xff0c;往往会遇到数据库迁移的任务。如果数据量不是特别大&…

【unity3D】Transform组件(如何访问和获取Transform组件)

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的Transform组件 Transform组件 基础知识介绍三个成员变量常用属性扩展 Transform的相关查找方法静态方法 基础知识 介绍 在Unit…

ELK(一)—介绍

一、ELK介绍 ELK是指Elasticsearch、Logstash和Kibana&#xff0c;这三个开源软件构成了一个功能强大的日志管理和分析平台。Elasticsearch作为分布式搜索引擎&#xff0c;负责实时存储和检索大规模数据&#xff1b;Logstash用于从多个数据源采集、处理和传输日志数据&#xff…

分包(微信小程序)

首先&#xff0c;微信小程序中使用分包是为了减少首屏的请求&#xff0c;因为微信小程序会默认下载主包内的内容并展示到页面上&#xff0c;但是随着业务量的增加&#xff0c;代码量也会越来越大。会导致我们启动小程序的时候首页加载速度过慢的这个问题。这时我们就可以采用分…