C++ – 面向对象编程方法

“以对象为基础(object-based)”的类机制无法针对如”are-a-kind-of(隶属同类)”的Book类的共通性质进行系统化的划分(如:RentalBook、AudioBook、InterativeBook)。因此,类间的关系有赖于”面向对象编程模型(object-oriented programming model)”加以设定。

面向对象编程概念的两项最主要特质是:继承(inheritance)和多态(polymorphism)。前者使我们得以将一群相关的类组织起来,并让我们得以分享其间的共通数据和操作行为;后者让我们在这些类之上进行编程时,可以如同操控单一个体,而非相互独立的类,并赋予我们更多弹性来加入或移除任何特定类。

1)继承(inheritance)

继承机制定义了父子(parent/child)关系。父类(parent)定义了所有子类(children)共通的公有接口(public interface)和私有实现(private implementation)。每个子类都可以增加或覆盖(override)继承而来的东西,以实现其自身独特的行为。
在C++中,父类被称为基类(base class),子类被称为派生类(derived class)。父类和子类之间的关系则称为继承体系(inheritance hierarchy)。

2)多态(polymorphism)

让基类的pointer或reference得以十分透明的(transparently)指向其任何一个派生类的对象。

void function(LibMat &mat) {

    mat.check_in();

}

静态绑定(static binding):
程序执行之前就已经解析出应该调用哪一个函数。即编译器在编译时就依据mat所属的类决定应执行哪一个check_in()函数。
动态绑定(dynamic binding):
在面向对象编程方法中,编译器无法得知哪一份check_in()函数会被调用。每次function执行时,仅能在执行过程中依据mat所指的实际对象来决定调用哪一个check_in()。”找出实际被调用的究竟是哪一个派生类的check_in()函数”这一解析操作会延迟至运行时(run-time)才进行。

多态和动态绑定的特性只有在使用pointer或reference时才能发挥。

#include

class LibMat
{
public:

    LibMat() { std::cout << "LibMat::LibMat() default constructor!\n"; }

    virtual ~LibMat() { std::cout << "LibMat::~LibMat() destructor!\n"; }
    virtual void print() const { std::cout << "LibMat::print() -- I am a LibMat object!\n"; }
};

class Book : public LibMat
{
public:
    Book(const std::string &title, const std::string &author)
        : _title(title), _author(author)
    {
        std::cout << "Book::Book( " << _title
                  << ", " << _author << " ) constructor!\n";
    }

    virtual ~Book()
    {
        std::cout << "Book::~Book() destructor!\n";
    }

    virtual void print() const
    {
        std::cout << "Book::print() -- I am a Book object!\n"
                  << "My title is: " << _title << '\n'
                  << "My author is: " << _author << std::endl;
    }

    const std::string &title() const { return _title; }
    const std::string &author() const { return _author; }

protected:
    std::string _title;
    std::string _author;
};

class AudioBook : public Book
{
public:
    AudioBook(const std::string &title,
              const std::string &author, const std::string &narrator)
        : Book(title, author), _narrator(narrator)
    {
        std::cout << "AudioBook::AudioBook( " << _title
                  << ", " << _author
                  << ", " << _narrator
                  << " ) constructor!\n";
    }

    ~AudioBook()
    {
        std::cout << "AudioBook::~AudioBook() destructor!\n";
    }

    virtual void print() const
    {
        std::cout << "AudioBook::print() -- I am an AudioBook object!\n"
                  << "My title is: " << _title << '\n'
                  << "My author is: " << _author << '\n'
                  << "My narrator is: " << _narrator << std::endl;
    }
    const std::string &narrator() const { return _narrator; }

protected:
    std::string _narrator;
};

void print(const LibMat &mat)
{
    std::cout << "in global print(): about to print mat.print()\n";

    mat.print();
}

int main()
{
    AudioBook ab("Mason and Dixon", "Thomas Pynchon", "Edwin Leonard");
    std::cout << "The title is " << ab.title() << '\n'
              << "The author is " << ab.author() << '\n'
              << "The narrator is " << ab.narrator() << std::endl;
}

输出结果:

LibMat::LibMat() default constructor!

Book::Book( Mason and Dixon, Thomas Pynchon ) constructor!

AudioBook::AudioBook( Mason and Dixon, Thomas Pynchon, Edwin Leonard ) constructor!The title is Mason and Dixon
The author is Thomas Pynchon
The narrator is Edwin Leonard
AudioBook::~AudioBook() destructor!

Book::~Book() destructor!

LibMat::~LibMat() destructor!

在上述示例的基础上我们运行如下程序:

void print(LibMat object, const LibMat *pointer, const LibMat &reference)
{
    std::cout << "object.print();" << std::endl;
    object.print();
    std::cout << "pointer->print();" << std::endl;
    pointer->print();
    std::cout << "reference.print();" << std::endl;
    reference.print();
}
int main()
{
    AudioBook ab("Mason and Dixon", "Thomas Pynchon", "Edwin Leonard");
    print(ab, &ab, ab);
}

我们会得到如下输出:

object.print();
LibMat::print() -- I am a LibMat object!

pointer->print();
AudioBook::print() -- I am an AudioBook object!

My title is: Mason and Dixon
My author is: Thomas Pynchon
My narrator is: Edwin Leonard
reference.print();
AudioBook::print() -- I am an AudioBook object!

My title is: Mason and Dixon
My author is: Thomas Pynchon
My narrator is: Edwin Leonard

我们可以看到在LibMat object中虽然传入的对象时AudioBook但是调用的print()却是基类LibMat的print()函数。这是因为当我们声明一个基类的实例对象时,分配的内存空间不足以容纳我们传入的派生类对象,其子对象部分便被裁切(sliced off)了,只复制了基类的data member部分。因此多态(polymorphism)需要一层间接性。

#include
int main()
{
    Book book("Mason and Dixon", "Thomas Pynchon");
    LibMat *lm = &book;
    std::cout << typeid(*lm).name() << std::endl;

    if(typeid(*lm) == typeid(Book)) {
        Book *b = static_cast<Book*>(lm);
        b->print();
    }

    if(Book *b = dynamic_cast<Book*>(lm)) {
        b->print();
    }
}

Original: https://blog.csdn.net/weixin_45919985/article/details/128326757
Author: Spikeeee-
Title: C++ – 面向对象编程方法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/777642/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 对DataFrame各行列累乘:prod()函数

    【小白从小学Python、C、Java】【Python-计算机等级考试二级】【Python-数据分析】对DataFrame各行列累乘prod()函数 选择题下列说法错误的是? im…

    Python 2023年8月8日
    058
  • python带你采集西瓜无水印美女舞蹈视频数据~

    Original: https://www.cnblogs.com/Qqun261823976/p/16700068.htmlAuthor: python倩Title: pytho…

    Python 2023年6月9日
    072
  • python中的scrapy爬虫_基于Python的Scrapy爬虫入门:代码详解

    CTO练习营 | 12月3-5日,深圳,是时刻成为优良的技巧治理者了 根据属性名称很轻易知道对应的内容含义,这里我们只需关怀 postlist 这个属性,它对应的一个数组元素就是一…

    Python 2023年10月6日
    044
  • 面向对象的特点

    面向对象的特点 封装 什么是封装? ​ 封装表面意思就是封锁和包装;把信息进行隐藏起来;是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被…

    Python 2023年10月19日
    043
  • Nethunter·键盘攻击

    键盘攻击 (更新中。。。) NetHunter HID 键盘攻击 DuckHunter HID 攻击 NetHunter BadUSB 攻击 正如官方给的演示图那样,只要编译好脚本…

    Python 2023年6月12日
    063
  • 基于Django框架的网络云盘设计

    基于Django框架的网络云盘设计 网络云盘设计流程(第一篇) * 前言 前期准备与环境搭建 创建一个Django工程,跑一个HelloWorld 网盘设计简介及成果展示 功能1,…

    Python 2023年8月6日
    069
  • [Python] pop()函数

    pop()函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 list.pop([index=-1]) 要移除列表元素的索引值,不能超过列表总长度,默认为inde…

    Python 2023年8月1日
    084
  • 利用云服务器发布项目

    平时开发我会写一些小demo,我自己觉得有用的会集中起来形成一个项目,本来想利用gitee的gitee page直接部署出来,但后面了解了下,它只支持官网之类的静态页面,无法与后台…

    Python 2023年10月12日
    043
  • 【深度强化学习】多智能体算法汇总

    0 Preliminaries 在多智能体强化学习算法中,两个主要的技术指标为合理性与收敛性。 合理性(rationality):在对手使用一个恒定策略的情况下,当前智能体能够学习…

    Python 2023年9月27日
    049
  • 34. 池化层 / 汇聚层

    1. 池化层 如果我们拍摄黑白之间轮廓清晰的图像X,并将整个图像向右移动一个像素,即Z[i, j] = X[i, j + 1],则新图像Z的输出可能大不相同。而在现实中,随着拍摄角…

    Python 2023年10月27日
    041
  • 基于diffusion models的无监督Image-to-Image转化

    ### 回答1: Q: 什么是”调色板:图像到图像扩散模型”? A: 调色板:图像到图像扩散模型是一种图像处理技术,它利用调色板(一组预定义的颜色)将一张图…

    Python 2023年10月8日
    041
  • 几个精灵同时在窗口中显示

    让窗口内不止存在一个自由运动的活动精灵:(这里以3个精灵为例)1.首先在actor里建立好这两个pythonfile:1.行走活动2.行走的战士2.在actor里再建立:1.行走解…

    Python 2023年9月25日
    044
  • 【愚公系列】2022年04月 Python教学课程 73-DRF框架之限流

    限流类似于权限,因为它确定是否应对请求进行授权。限制指示临时状态,用于控制客户端可以向 API 发出的请求速率。 与权限一样,可以使用多个限制。您的 API 可能对未经身份验证的请…

    Python 2023年8月4日
    053
  • Ubuntu安装mysql并连接(使用vscode插件)

    在学习Django的过程中,我需要使用到mysql数据库。所以今天就说一说怎么安装mysql及其连接。 一、安装 1.更新源:sudo apt update 2.安装服务端:sud…

    Python 2023年8月4日
    047
  • 详细解读numpy中transpose()函数(附带实例帮助理解)

    在Numpy对矩阵的转置中,我们可以用transpose()函数来处理。 这个函数的运行是非常反常理的,可能会令人陷入思维误区。 我就是在学习的过程中感到很难理解,但所幸查阅了很多…

    Python 2023年8月25日
    051
  • 【python学习】单元测试框架pytest(二)-29

    pytest:编写测试用例 – 收集测试用例 – 执行测试用例 – 生成测试报告 编写测试用例: 用例名称、用例步骤、预期结果 、实际结果 、前…

    Python 2023年9月10日
    093
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球