C++三大特性封装继承多态

本文详细介绍了C++的三大核心特性:封装、继承和多态。深入探讨了这些特性的概念、实现方式及其应用场景,包括虚函数、纯虚函数、函数重写与重载的区别等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++的三大特性:
封装、继承、多态
封装:将一类事物所共有的属性和行为方法进行总结,封装在一个类中。该类的形成过程称为封装,该封装的类实例化的对象具有类的所有属性和行为方法。
封装的类的内部按照访问限定符可以分为:(public:)公有部分、(protected:)保护部分、(private:)私有部分。

继承:继承是把一个已经成型(封装好)的类继承到一个新形成的类中,一般将被继承的类称为父类(基类),主动继承的称为子类(派生类)。
继承的作用是为了实现代码的重用性。即父类的代码继承到子类任然可用。
继承分为:公有继承 、 保护继承 、 私有继承。
公有继承: (格式: class Derived:public Base)
父类的共有部分继承到子类的公有部分,父类的保护部分继承到子类的保护部分,父类的私有部分继承到子类的私有部分(父类的私有部分在子类不可访问)。
保护继承: (格式: class Derived:protected Base)
父类的共有部分继承到子类的保护部分,父类的保护部分继承到子类的保护部分,父类的私有部分继承到子类的私有部分(父类的私有部分在子类不可访问)。
私有继承: (格式: class Derived:private Base)
父类的所有都继承到子类的私有部分,父类的私有部分在子类不可访问。
多态
什么是多态:
调用相同的接口,表现出不同的结果。
如何实现多态:
通过定义和重写虚函数,通过基类的指针或引用指向派生类对象,通过基类的指针或引用调用虚函数,实现接口的高度统一。简而言之就是调用相同的接口表现不同的结果。


什么是虚函数?


virtual 函数返回值 函数名(形参);
只有成员函数可以是虚函数。
虚函数就是允许派生类重写它。
函数重写:
1.返回值相同,函数名相同,参数相同,
2.派生类中的virtual关键字可有可无,但基类的函数必须有virtual关键字。
3.作用域不同,一个位于基类,一个位于派生类
基类的指针可以隐式类型转换成派生类对象的地址。反之不行。
基类的引用可以隐式类型转换成派生类对象的别名。反之不行。
抽象类:包含纯虚函数的类叫抽象类,抽象类无法实例化(无法定义对象)
纯虚函数只有声明,不需要基类中实现。
如何声明纯虚函数:
virtual 返回值类型 函数名(形参)=0;

纯虚函数被派生类继承以后,如果被派生类定义,派生类就不是抽象类,如果在派生类中没有定义纯虚函数,派生类也将变成抽象类。


覆盖(函数重写)、函数隐藏、函数重载的区别?
成员函数隐藏(也称重定义)
A、不在同一个作用域(分别位于派生类与基类)
B、函数名字相同
C、返回值可以不同
D、参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意与重载的区别)
E、参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意与覆盖的区别)
成员函数覆盖(override,也称重写)
是指派生类重新定义基类的虚函数,特征如下:
A、不同的作用域(分别位于派生类与基类)
B、函数名字相同
C、参数相同
D、基类函数必须有virtual关键字,不能有static
E、返回值相同
F、重写函数的权限访问限定符可以不同
成员函数重载(overload)
是指函数名相同,参数不同(数量、类型、次序),特征如下:
A、相同的范围(在同一个作用域中)
B、函数名字相同
C、参数不同
D、virtual 关键字可有可无
E、返回值可以不同

函数重写的原理:通过查虚函数表,来得到对象的虚函数的地址

虚析构
在析构函数前加virtual关键字有什么作用?
防止内存泄漏 (delete p的时候,如果析构函数是虚函数,这时只会看p所赋值的对象,如果对象是派生类的对象,就会调用派生类的析构函数
,如果p赋值的是基类的对象,就会调用基类的析构函数)
如果析构函数不是虚函数,在delete p,调用析构函数,只会看指针的数据类型,而不会看赋值的对象,所以,会有内存泄漏
explicit 关键字的用法:
只能修饰构造函数,防止单参数的构造函数隐式类型转换,把一个常量转换成一个对象。
在没有加explicit之前,可以把一个常量赋给一个对象。

推荐构造函数前最好加explict ,析构函数前最好加virtual进行修饰。

<think>好的,我现在需要详细讲解C++封装继承多态特性。首先,我需要回忆一下这个概念的基本定义,然后思考如何用清晰的结构组织内容,确保符合用户的要求。 首先,封装封装是面向对象编程的基础,主要目的是隐藏对象的内部细节,只暴露必要的接口。我应该解释封装的作用,比如数据保护和简化使用。然后举一个类的例子,比如学生类,里面有私有成员变量和公有方法。需要注意用中文术语,同时确保例子中的代码符合C++语法。 接下来是继承继承允许创建新类基于现有类,这样可以复用代码并建立类之间的关系。需要说明基类和派生类的概念,访问权限如public继承的影响。例子可以用动物基类,派生狗和猫类,展示如何继承和重写方法。同时,要提到多重继承,但可能简单带过,避免复杂化。 然后是多态多态分为编译时和运行时两种。编译时多态比如函数重载和模板,运行时多态通过虚函数和继承实现。重点在于虚函数和纯虚函数,抽象类的概念。例子可以用形状基类,派生圆和矩形,展示如何通过基类指针调用不同派生类的方法。动态绑定和虚函数表的概念可能需要简要提及,但不要过于深入底层。 在结构上,每个特性应该作为一个点,分点讲解作用、语法示例、应用场景。要确保每个部分都有代码示例,并且这些示例正确使用$$...$$格式,行内公式用$...$。比如在讲解继承时,基类和派生类的定义需要用代码块展示,并正确标记。 需要检查是否有遗漏的重要点,比如封装的访问修饰符(private, public, protected),继承中的保护继承和私有继承多态中override关键字和虚析构函数的重要性。这些细节可以适当提到,但以基础讲解为主。 用户可能的问题包括为什么需要这些特性,实际应用中的例子,以及常见错误。比如,如果不使用虚函数,多态无法实现,导致静态绑定。或者继承中切片问题。可能需要在讲解时简要提及这些注意事项,但主要围绕特性本身。 最后,确保语言口语化,避免使用专业术语过于密集,适当分段,让读者容易理解。同时,代码示例要简洁,突出关键部分,比如虚函数的使用,继承的语法结构。检查LaTeX格式是否正确,尤其是代码块是否用$$...$$包裹,行内变量如$MyClass$是否正确。 总结,结构致如下: 1. 封装:定义、作用、示例代码 2. 继承:定义、类型、示例代码、应用 3. 多态:类型(编译时/运行时)、虚函数、示例代码、抽象类 4. 总结者联系和重要性 确保每个部分过渡自然,逻辑清晰,帮助用户逐步理解。可能需要多次调整示例,确保正确性和易懂性。比如在封装中使用学生类,设置姓名年龄,私有变量,公有方法;继承中的动物类;多态中的形状类。这些例子比较经典,容易理解。 现在开始组织内容,按照结构详细阐述每个特性,并插入正确的代码示例,用LaTeX格式标记。</think>以下是对C++特性封装继承多态)的详细讲解,结合代码示例逐步说明: --- ### 一、封装(Encapsulation) #### 1. 作用 - **数据隐藏**:将对象的内部实现细节隐藏,只暴露必要接口。 - **安全性**:通过访问权限控制,防止外部直接修改敏感数据。 - **模块化**:将数据和操作数据的方法绑定,提高代码可维护性。 #### 2. 语法实现 - 使用`private`/`protected`/`public`关键字控制访问权限。 - 示例: ```cpp class Student { private: // 封装数据 std::string name; int age; public: // 暴露接口 void setName(const std::string& newName) { name = newName; } void setAge(int newAge) { if (newAge > 0) age = newAge; // 通过方法验证数据合法性 } }; ``` --- ### 二、继承(Inheritance) #### 1. 作用 - **代码复用**:派生类可直接使用基类的属性和方法。 - **层次化设计**:通过类之间的层级关系建模现实问题。 #### 2. 语法实现 - 使用`class 派生类 : 访问权限 基类`定义继承关系。 - 访问权限决定基类成员在派生类中的可见性(常用`public`继承)。 - 示例: ```cpp class Animal { // 基类 public: void eat() { std::cout << "Eating..." << std::endl; } }; class Dog : public Animal { // 派生类 public: void bark() { std::cout << "Woof!" << std::endl; } }; // 使用 Dog myDog; myDog.eat(); // 继承自基类 myDog.bark(); // 派生类自有方法 ``` --- ### 多态(Polymorphism) #### 1. 类型 - **编译时多态**:通过函数重载和模板实现。 - **运行时多态**:通过虚函数和继承实现(动态绑定)。 #### 2. 运行时多态实现 - **虚函数**:使用`virtual`关键字声明,允许派生类重写。 - **纯虚函数**:定义抽象类(不可实例化),语法为`virtual 返回类型 函数名() = 0;`。 - 示例: ```cpp class Shape { // 抽象基类 public: virtual double area() const = 0; // 纯虚函数 }; class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) {} double area() const override { // 重写虚函数 return 3.14 * radius * radius; } }; // 使用 Shape* shape = new Circle(5.0); std::cout << shape->area(); // 动态调用Circle::area() delete shape; ``` #### 3. 关键机制 - **虚函数表(vtable)**:编译器为含虚函数的类生成表,存储函数指针。 - **动态绑定**:程序运行时根据对象类型决定调用的函数。 --- ### 四、者联系与总结 | 特性 | 核心思想 | 应用场景 | |--------|------------------------------|--------------------------| | 封装 | 隐藏细节,暴露接口 | 数据保护、模块化设计 | | 继承 | 层次化复用代码 | 扩展功能、类关系建模 | | 多态 | 同一接口表现不同行为 | 接口抽象、动态行为扩展 | #### 实际开发建议 1. 优先用组合而非继承,避免过度层级。 2. 基类析构函数应声明为`virtual`,防止内存泄漏。 3. 使用`override`关键字明确重写虚函数,提高代码可读性。 通过合理运用这特性,可以显著提升代码的可扩展性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值