C++学习笔记——类继承

news2025/1/12 3:42:23

目录

一、一个简单的基类

1.1封装性

1.2继承性

1.3虚函数

1.4多态性

二、基类

2.1一个简单的C++基类的示例

2.2 Animal是一个基类。

三、继承

3.1概念

3.2is-a关系

 3.3多态公有继承

 3.4静态联编和动态联编

3.5访问控制

3.6ABC理念


一、一个简单的基类

C++中的基类是一个抽象的类,它作为其他相关类的通用特性和行为的模板。基类定义了一组共享的成员函数、数据成员和虚函数,这些成员可以被派生类继承和扩展。

以下是对C++简单的基类概念的介绍:

1.1封装性

基类封装了一些数据成员和成员函数,以提供对派生类的内部实现的抽象。这样,派生类可以继承基类的属性和行为,并根据需要进行修改或扩展。

1.2继承性

派生类可以通过继承基类来获得其成员函数和数据成员。这意味着派生类可以重用基类的代码,从而减少了代码的冗余。派生类可以通过关键字publicprotectedprivate来指定继承方式。

1.3虚函数

基类中的虚函数允许派生类根据自己的特定需求来重新定义这些函数。通过在基类中将函数声明为virtual,可以在派生类中使用相同的函数名来覆盖基类中的实现。这样,通过基类指针或引用调用虚函数时,将根据对象的实际类型来执行适当的函数。

1.4多态性

多态性是面向对象编程的一个重要概念,允许以通用的方式处理不同类型的对象。通过使用基类指针或引用来引用派生类的对象,可以以相同的方式调用基类的成员函数,从而实现代码的灵活性和可扩展性。

二、基类

提供了一种层次结构,用于组织和管理相关的类,并促进代码的重用和结构化。通过继承和多态性的机制,基类和派生类之间建立了一种强大的关系,使得面向对象程序具有更好的可维护性和可扩展性。在C++中,一个简单的基类是一个抽象的类,它提供了其他相关类的通用特性和行为。基类通常包含成员函数、数据成员和虚函数。

下面是:

2.1一个简单的C++基类的示例

class Animal {
protected:
    std::string name;
    int age;

public:
    Animal(const std::string& _name, int _age) : name(_name), age(_age) {}

    void eat() {
        std::cout << name << " is eating." << std::endl;
    }

    void sleep() {
        std::cout << name << " is sleeping." << std::endl;
    }

    virtual void sound() {
        std::cout << name << " makes a sound." << std::endl;
    }
};

在这个示例中,它具有以下特点:

2.2 Animal是一个基类。

表示动物

  • 数据成员:name表示动物的名字,age表示动物的年龄。这些成员被声明为protected,可以被派生类访问。
  • 构造函数:构造函数用于初始化动物的名字和年龄。
  • 成员函数:eat()sleep()是普通成员函数,表示动物的吃和睡觉行为。
  • 虚函数:sound()是一个虚函数,表示动物发出声音的行为。它被声明为虚函数,以便派生类可以覆盖该函数来实现自己特定的声音行为。

使用这个基类,你可以创建派生类来表示不同种类的动物,例如狗、猫、鸟等。派生类可以继承基类的成员函数和数据成员,并可以添加自己特定的成员函数和数据成员。

基类允许你通过多态性的概念,以相同的方式对待不同类型的对象。例如,你可以使用基类指针或引用来操作派生类的对象,从而实现代码的灵活性和可扩展性。

这个简单的基类示例展示了面向对象编程中的封装、继承和多态的概念。通过基类和派生类的组合,可以实现代码的重用和结构化。

三、继承

3.1概念

是面向对象编程中的一种重要概念,它允许一个类(称为派生类或子类)从另一个类(称为基类或父类)继承属性和行为。

通过继承,派生类可以获得基类的成员函数和数据成员,并可以在其基础上添加自己特定的功能。这样可以实现代码的重用,减少了冗余的代码编写。

在C++中,继承有三种方式:

  1. 公有继承(public inheritance):使用public关键字,派生类将继承基类的公有成员和保护成员。公有继承表示派生类与基类之间存在"是一个"的关系,派生类的对象可以被视为基类的对象。

  2. 保护继承(protected inheritance):使用protected关键字,派生类将继承基类的保护成员,并将其作为自己的保护成员。保护继承表示派生类与基类之间存在一种特殊的关系,派生类的对象不能被视为基类的对象。

  3. 私有继承(private inheritance):使用private关键字,派生类将继承基类的私有成员,并将其作为自己的私有成员。私有继承表示派生类与基类之间存在一种实现细节的关系,派生类的对象不能被视为基类的对象。

继承提供了一种机制,通过定义一个通用的基类,使得派生类可以继承这些通用特性,并根据需要进行修改和扩展。在继承关系中,基类通常包含了派生类共有的特征和行为,而派生类则添加了自己特定的特征和行为。

需要注意的是,派生类可以通过重写(覆盖)基类的成员函数来改变其行为,这是通过使用virtual关键字和虚函数实现的。此外,C++支持多重继承,允许一个派生类从多个基类继承属性和行为。

在面向对象编程中,is-a关系是一种重要的概念,用于描述一个类是否属于另一个类的一种特殊情况,通常也称为继承关系。

3.2is-a关系

表示一个类是另一个类的一种类型或子类,即派生类是基类的一种特例。例如,狗是一种动物,所以Dog类是Animal类的子类,可以使用公有继承实现。

is-a关系通常表示为"派生类 is a 基类"的形式。在C++中,使用公有继承可以实现is-a关系,因为派生类将继承基类的公有成员和保护成员,可以像基类一样使用这些成员。

例如:

// 定义一个基类Animal
class Animal {
public:
    void eat();
    void sleep();
};

// 定义一个派生类Dog,它是Animal的子类
class Dog : public Animal {
public:
    void bark();
};

在上面的例子中,Dog类是Animal类的子类,因此可以使用Dog对象调用eat()sleep()函数,这就体现了is-a关系。

is-a关系是面向对象编程中最基本的关系之一,它反映了现实世界中的分类关系。通过定义一个通用的基类,我们可以将代码组织成层次结构,实现代码的重用和结构化。

 3.3多态公有继承

多态是面向对象编程中的一种重要概念,它允许一个对象在不同的情况下表现出不同的行为,是面向对象程序设计中最重要的特性之一。

公有继承可以提供多态的实现方式之一,这种多态称为动态多态(或运行时多态)。简单来说,动态多态指的是在运行时根据对象的实际类型来调用相应的函数。

在C++中,使用虚函数实现动态多态。虚函数是一种特殊的成员函数,它通过关键字virtual进行声明,并且在派生类中可以被重写。当基类的指针或引用指向派生类的对象时,可以通过虚函数实现动态多态。

例如:

// 定义一个基类Animal
class Animal {
public:
    virtual void makeSound();
};

// 定义一个派生类Dog,它重写了基类的makeSound()函数
class Dog : public Animal {
public:
    void makeSound() override;
};

// 定义一个派生类Cat,它重写了基类的makeSound()函数
class Cat : public Animal {
public:
    void makeSound() override;
};

在上面的例子中,Animal类定义了虚函数makeSound()DogCat类分别重写了这个函数。当基类指针或引用指向DogCat对象时,可以通过调用makeSound()函数来实现动态多态。

例如:s

Animal* animal = new Dog;
animal->makeSound(); // 调用Dog类的makeSound()函数

animal = new Cat;
animal->makeSound(); // 调用Cat类的makeSound()函数

在上面的例子中,animal指针先指向Dog对象,然后调用makeSound()函数时会调用Dog类的makeSound()函数;之后animal指针又指向Cat对象,调用makeSound()函数时会调用Cat类的makeSound()函数。这就体现了动态多态的特性。

总之,通过公有继承和虚函数,C++提供了一种强大的多态机制,可以使代码更加灵活和易于扩展。

 3.4静态联编和动态联编

静态联编(静态绑定)和动态联编(动态绑定)是面向对象编程中两种不同的函数调用机制。

  1. 静态联编(静态绑定): 静态联编是指在编译时确定调用哪个函数的机制,也称为早期绑定。在静态联编中,函数调用的解析是基于变量的静态类型(编译时类型)进行的。编译器会根据变量的声明类型来决定调用哪个函数,并且这个决定是在编译阶段确定的。

静态联编适用于非虚函数和静态函数。由于在编译时确定了函数的调用,因此静态联编具有较高的执行效率,但缺少灵活性和多态性。

  1. 动态联编(动态绑定): 动态联编是指在运行时确定调用哪个函数的机制,也称为晚期绑定。在动态联编中,函数调用的解析是基于变量的实际类型(运行时类型)进行的。编译器会根据对象的实际类型来决定调用哪个函数,这个决定是在运行时确定的。

动态联编适用于虚函数。通过使用虚函数和基类指针或引用,可以实现在运行时根据对象的实际类型来调用相应的函数,实现多态性。动态联编提供了更高的灵活性和可扩展性,但在运行时需要额外的开销。

总结:

  • 静态联编是在编译时确定函数调用的机制,适用于非虚函数和静态函数,执行效率较高。
  • 动态联编是在运行时确定函数调用的机制,适用于虚函数,可以实现多态性,具有更高的灵活性和可扩展性,但在运行时需要额外开销。
#include <iostream>

// 基类 Animal
class Animal {
public:
    void makeSound() {
        std::cout << "Animal makes a sound." << std::endl;
    }
};

// 派生类 Dog
class Dog : public Animal {
public:
    void makeSound() {
        std::cout << "Dog barks." << std::endl;
    }
};

// 派生类 Cat
class Cat : public Animal {
public:
    void makeSound() {
        std::cout << "Cat meows." << std::endl;
    }
};

int main() {
    Animal animal;
    Dog dog;
    Cat cat;

    // 静态联编 - 根据变量的静态类型调用函数
    animal.makeSound();  // 输出: Animal makes a sound.
    dog.makeSound();     // 输出: Dog barks.
    cat.makeSound();     // 输出: Cat meows.

    // 动态联编 - 使用指针或引用调用虚函数
    Animal* animalPtr1 = &animal;
    Animal* animalPtr2 = &dog;
    Animal* animalPtr3 = &cat;

    animalPtr1->makeSound(); // 输出: Animal makes a sound.
    animalPtr2->makeSound(); // 输出: Dog barks.
    animalPtr3->makeSound(); // 输出: Cat meows.

    return 0;
}

在上述示例中,我们定义了一个基类 Animal 和两个派生类 DogCatAnimal 类中的 makeSound 函数并非虚函数,因此在静态联编中,无论使用基类对象还是派生类对象调用该函数,都会调用基类的实现。

然而,当我们使用基类指针或引用指向派生类的对象时,通过动态联编(虚函数)来调用 makeSound 函数时,将根据对象的实际类型来确定应该调用哪个类的实现。这样,我们可以实现多态性,即相同的函数调用可以根据对象的实际类型产生不同的行为。

3.5访问控制

是面向对象编程中的一个重要概念,用于限制类成员的访问权限。通过访问控制,我们可以控制哪些部分的代码可以访问类的成员变量和成员函数,以确保数据的封装性和安全性。

在大多数面向对象编程语言中,通常有以下几种访问控制修饰符:

  1. 公有(Public):公有成员可以在任何地方被访问,包括类的内部和外部。其他类和对象都可以直接访问公有成员。

  2. 私有(Private):私有成员只能在类的内部被访问,其他类和对象无法直接访问私有成员。私有成员通常用于实现类的内部逻辑和数据隐藏。

  3. 保护(Protected):保护成员可以在类的内部和派生类中被访问。派生类中的成员函数可以访问基类的保护成员,但其他类和对象无法直接访问保护成员。

不同的编程语言可能使用不同的关键字来表示这些访问控制修饰符,例如:

  • C++ 中使用 publicprivateprotected 关键字。
  • Java 中使用 publicprivateprotected 关键字。
  • Python 中使用命名约定(例如 _ 前缀)来表示私有成员,而没有严格的访问控制修饰符。

下面是一个 C++ 的示例代码,演示了访问控制的用法:

#include <iostream>

class MyClass {
public:    // 公有成员
    int publicVar;

    void publicMethod() {
        std::cout << "This is a public method." << std::endl;
    }

private:   // 私有成员
    int privateVar;

    void privateMethod() {
        std::cout << "This is a private method." << std::endl;
    }

protected: // 保护成员
    int protectedVar;

    void protectedMethod() {
        std::cout << "This is a protected method." << std::endl;
    }
};

int main() {
    MyClass obj;
    obj.publicVar = 10;     // 可以直接访问公有成员变量
    obj.publicMethod();     // 可以直接调用公有成员函数

    // 下面的语句将导致编译错误,因为私有成员和保护成员无法在外部访问
    // obj.privateVar = 20; 
    // obj.privateMethod();
    // obj.protectedVar = 30; 
    // obj.protectedMethod();

    return 0;
}

在上述示例中,我们定义了一个类 MyClass,其中包含公有、私有和保护成员。在 main 函数中,我们可以直接访问和调用公有成员,但无法访问私有和保护成员。

这种访问控制机制可以帮助我们保护类的内部实现细节,封装数据并提供统一的接口。通过对成员的合理访问控制,我们可以提高代码的安全性、可维护性和可扩展性。

3.6ABC理念

ABC理念是一种管理思想,是Activity-Based Costing(基于活动成本核算)的缩写,有时也被称为Activity-Based Management(基于活动管理)。它在20世纪80年代末由哈佛商学院教授Robert S. Kaplan和Robin Cooper提出,旨在帮助企业更精确地计算成本和经营绩效,以优化产品和服务的设计、生产和销售过程。

ABC理念认为,企业的成本不仅取决于直接材料、直接人工和制造费用等传统成本指标,还受到活动成本的影响。活动成本是指生产或提供产品和服务所需的所有活动和资源的成本,包括设备、人力、能源、时间等。ABC理念通过对活动进行分析和定价,将成本更准确地分配到各个产品、服务或客户上,以便更好地评估其贡献度和盈利能力。

ABC理念的主要思想可以概括为以下几点:

  1. 强调活动的重要性:企业的成本和绩效不仅取决于产品和服务本身,还受到生产和销售过程中的各种活动的影响。因此,要准确计算成本和评估绩效,就需要先详细了解和分析这些活动。

  2. 区分成本驱动因素:ABC理念认为,不同的活动对成本的贡献程度不同。通过区分成本驱动因素(也就是导致各项活动发生的原因),可以更好地了解成本结构和优化资源配置。

  3. 精细计算成本:ABC理念强调将成本精细化到各个活动和产品/服务上,以便更准确地定价和分配成本。这可以帮助企业更好地了解各种产品和服务的盈利能力,并且优化产品和服务的设计、制造和销售过程。

  4. 以客户为中心:ABC理念认为,客户是企业最重要的资产。因此,在分析成本和评估绩效时,要以客户为中心,关注他们的需求和反馈,并根据客户的需求来制定产品和服务的设计、生产和销售策略。

ABC理念在管理实践中得到了广泛应用,特别是在制造业和服务业中。它的主要优点包括:

  1. 更准确地计算成本和评估绩效,有助于优化资源配置和提高盈利能力。

  2. 帮助企业更好地理解产品和服务的盈利能力,以便优化产品和服务的设计、制造和销售过程。

  3. 强调客户需求和反馈,有助于提高客户满意度和忠诚度。

  4. 促进内部控制和管理流程的优化,有助于提高企业效率和效益。

ABC理念也存在一些挑战和限制。例如,实施ABC理念需要大量的数据收集和分析工作,对企业的信息系统和人力资源提出了较高的要求。此外,ABC理念也可能导致某些活动过度成本化,从而影响企业的有效性和效率。因此,在实施ABC理念时需要慎重考虑,并结合实际情况进行适当的调整和优化。

 

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

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

相关文章

会声会影2024什么时间发布呢?会声会影2024会有那些新功能

近年来&#xff0c;随着科技的不断进步&#xff0c;各种软件的功能越来越强大&#xff0c;其中最为常用的莫过于视频编辑软件。而会声会影作为一款颇受欢迎的视频编辑软件&#xff0c;备受用户关注。那么&#xff0c;会声会影2024什么时间发布呢&#xff1f; 首先&#xff0c;我…

Mybatis基础---------增删查改

增删改 1、新建工具类用来获取会话对象 import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.io.Resources;import java.io.IOExcept…

算法复习——01背包

01背包 DP分析法要素有&#xff1a;集合&#xff0c;属性&#xff0c;状态计算 &#xff08;集合是指只考虑前i个&#xff0c;总体积小于等于j的所有选法&#xff0c;存取的属性是所有选法的最大值&#xff09; 状态方程计算&#xff08;所有选法可以分为2种不同的子集&#x…

数学建模day16-预测模型

本讲首先将介绍灰色预测模型&#xff0c;然后将简要介绍神经网络在数据预测中的应用&#xff0c;在本讲的最 后&#xff0c;我将谈谈清风大佬对于数据预测的一些看法。 注&#xff1a;本文源于数学建模学习交流相关公众号观看学习视频后所作 目录 灰色系统 GM(1,1)…

基于FPGAWS2812B的贪吃蛇方案设计(含源码)

第1章 基于FPGA&WS2812B的贪吃蛇方案设计 1.2 贪吃蛇游戏系统的功能需求分析 为了更好的实现我们的贪吃蛇游戏系统&#xff0c;我们需要对项目进行功能分析&#xff0c;利于我们对整个系统的分析、架构。 首先&#xff0c;对于整个游戏系统&#xff0c;我们需要界面来引…

Java基础 -04 List之CopyOnWriteArrayList

java集合有蛮多的类型&#xff0c;今天我们以CopyOnWriteArrayList和Vector进行相关介绍。 CopyOnWriteArrayList CopyOnWriteArrayList是Java集合框架中的一个线程安全的List实现类。它通过在修改操作时创建一个新的副本来实现线程安全性&#xff0c;因此称为"写时复制…

【Nuxt3】nuxt3目录文件详情描述:.nuxt、.output、assets、public、utils(一)

简言 nuxt3的中文网站 上次简单介绍了nuxt3创建项目的方法和目录文件大概用处。 这次详细说下.nuxt、.output、assets、public、utils五个文件夹的用处。 正文 .nuxt Nuxt在开发中使用.nuxt/目录来生成你的Vue应用程序。 为了避免将开发构建的输出推送到你的代码仓库中&…

使用HTTP/2在Linux上的Nginx服务器进行优化

随着互联网的发展&#xff0c;HTTP/2协议逐渐成为主流。与传统的HTTP/1.1相比&#xff0c;HTTP/2提供了更高的传输效率和更好的安全性。在Linux上使用Nginx服务器进行优化&#xff0c;我们可以充分利用HTTP/2的优势&#xff0c;提高网站的性能和用户体验。 1. 安装Nginx并启用…

【镜像制作】OS云主机镜像的制作——以H3C为例

一、云主机镜像简介 1&#xff0e;云主机镜像 云主机镜像不同于容器镜像&#xff0c;是一个含有引导分区、操作系统以及必要应用的单一文件&#xff0c;可以理解成是对整个系统安装光盘所有数据的克隆文件。云用户在创建和申请云主机时可通过选择不同的镜像来快速获取相应操作…

Linux/OpenAdmin

Enumeration nmap 用nmap扫描发现目标对外开放了22和80&#xff0c;端口详细信息如下 从nmap的结果看到&#xff0c;是apache的default page&#xff0c;使用工具跑一下目录&#xff0c;看了官 网文档的结果然后写个小字典节约时间&#xff0c;扫描结果如下 On the page at /…

【分布式技术】监控技术zabbix实操

目录 一、脚本监控nginx的连接状态 步骤一&#xff1a;做好nginx的配置 步骤二&#xff1a;完成监控数据脚本编写&#xff0c;并使用zabbix_get测试 步骤三&#xff1a;在zabbix agent配置目录中&#xff0c;编写以conf结尾的用户参数文件 步骤四&#xff1a;在zabbix web…

uniapp + node.js 开发问卷调查小程序

前后端效果图 后端&#xff1a;nodejs 12.8 ; mongoDB 4.0 前端&#xff1a;uniapp 开发工具&#xff1a;HBuilderX 3.99 前端首页代码 index.vue <!-- 源码下载地址 https://pan.baidu.com/s/1AVB71AjEX06wpc4wbcV_tQ?pwdl9zp --><template><view class&q…

探索设计模式的魅力:工厂方法模式

工厂方法模式是一种创建型设计模式&#xff0c;它提供了一种创建对象的接口&#xff0c;但将具体实例化对象的工作推迟到子类中完成。这样做的目的是创建对象时不用依赖于具体的类&#xff0c;而是依赖于抽象&#xff0c;这提高了系统的灵活性和可扩展性。 以下是工厂方法模式的…

在 Linux 本地部署 stable diffusion

由于工作站安装的是 ubuntu&#xff0c;卡也在上面&#xff0c;就只能在 ubuntu 上部署安装 stable diffusion 了。另外&#xff0c;Linux 上使用 stable diffusion 也会方便很多。 1 准备工作 NVIDIA 官网下载驱动&#xff0c;主要是为了规避多卡驱动不同的问题。由于本机是…

Linux下安装jdk、tomcat

linux下安装jdk、tomcat 一、linux下安装jdk1.1.下载Linux版本的JDK1.2.Linux安装JDk1.3.设置环境变量1.4.卸载JDK 二、linux下安装tomcat2.1.下载Linux版本的Tomcat2.2.在usr目录下新建tomcat目录2.3.进入到tomcat目录中解压下载的tomcat安装包2.4.配置环境变量-前提是已经安装…

C++ 设计模式之外观模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是外观模式 外观模式Facade Pattern , 也被称为“⻔⾯模式”&#xff0c;是⼀种结构型设计模式&#…

每日一练:LeeCode-102、二又树的层序遍历【二叉树】

本文是力扣LeeCode-102、二又树的层序遍历 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&…

visual studio的安装及scanf报错的解决

visual studio是一款很不错的c语言编译器 下载地址&#xff1a;官网 点击后跳转到以下界面 下滑后点击下载Vasual Sutdio&#xff0c;选择社区版即可 选择位置存放下载文件后&#xff0c;即可开始安装 安装时会稍微等一小会儿。然后会弹出这个窗口&#xff0c;我们选择安装位…

C++面试宝典第20题:计算岛屿数量

题目 在二维网格地图上,1 表示陆地,0 表示水域。如果相邻的陆地可以水平或垂直连接,则它们属于同一块岛屿。请进行编码,统计地图上的岛屿数量。比如:下面的二维网格地图,其岛屿数量为3。 解析 这道题主要考察应聘者对深度优先搜索、广度优先搜索、二维数组和矩阵操作、边…

Java代码审计FastJson反序列化利用链跟踪动态调试autoType绕过

目录 0x00 前言 0x01 基础参考 JNDI注入实例 使用type加入User类解析 FastJson历史漏洞简介 0x02 FastJson 1.2.24 利用链分析 调试过程 构造Poc思路 CC链关键流程 0x03 FastJson 1.2.25-1.2.47 利用链分析 1、开启autoTypeSupport&#xff1a;1.2.25-1.2.41 调试过…