当前位置: 首页 > wzjs >正文

石河子做网站sem 优化软件

石河子做网站,sem 优化软件,网站结构和布局区别,东莞阳光网疫情最新消息C封装、多态、继承C封装封装的定义与目的:把数据和方法统一组织在类中,对外隐藏内部实现,隐藏实现细节- 提供稳定接口- 保证数据有效性- 降低耦合性,提高维护性。封装的实现机制:类作用域、访问控制符、this指针类作用…

C++封装、多态、继承

C++封装

封装的定义与目的:把数据和方法统一组织在类中,对外隐藏内部实现,隐藏实现细节- 提供稳定接口- 保证数据有效性- 降低耦合性,提高维护性。

封装的实现机制:类作用域、访问控制符、this指针

类作用域

作用域:代码中名字(变量、函数等)可被识别和使用的有效范围。

在 C++ 中,常见作用域有:{全局作用域、命名空间作用域、函数作用域、块作用域、类作用域}

类的作用域控制了:类内部成员的名字有效范围、成员访问权限上下文

补充:

如果将类指针强转,则也可以访问到public数据。

访问控制符

虽然类作用域统一包含了所有成员,但访问控制符将它分成了不同“访问级别的区域”,

常见的访问控制符如下:

访问控制符

类内访问

子类访问

类外访问

private

允许

禁止

禁止

protected

允许

允许

禁止

public

允许

允许

允许

访问控制符(private / protected / public)的底层逻辑:

访问控制符是 “编译器层面的语义标签”,它不影响内存,不存在运行时信息,也不会生成额外的机器指令

编译器经历如下处理流程:源代码 -> 词法分析 -> 语法分析 -> 抽象语法树(AST) -> 语义分析 -> 生成中间表示(IR)

访问控制实现阶段:语法分析 + 语义分析阶段

编译器构建 AST(抽象语法树)时,会为每个类成员生成节点,并在节点上打上访问标签。

示例:

CXXRecordDecl MyClass

  |- FieldDecl x (access: private)

  |- FieldDecl y (access: protected)

  |- FieldDecl z (access: public)

  |- CXXMethod setX (access: public)

当编译器在解析类体的时候,它会维护一个 currentAccessSpecifier,一开始是 private(因为 class 默认是 private)。

遇到:private,它会更新 currentAccessSpecifier = AS_private

遇到:public,会更新 currentAccessSpecifier = AS_public

遇到:protected,会更新 currentAccessSpecifier = AS_ protected

然后,编译器接下来遇到的所有成员声明,就会统一打上当前 access 标记

访问控制符不会影响内存结构,无论成员是 public / protected / private,其在类对象中所占用的内存空间是完全一样的。

this指针

this 指针是 C++ 类的成员函数 内部隐式存在的一个指针,指向当前对象自身的地址。

  1. this 是一个 指针,类型为 ClassName* const(常量指针,指向不可变,但指向的对象可变)。
  2. 用于在成员函数内部明确表示 “当前对象”。
  3. 隐藏传入,每个成员函数的调用背后,都隐含传入了 this 指针。

示例:

class Person {

private:

    int age;

public:

    void setAge(int a) { this->age = a; }

};

编译器底层会转成类似这样:

void setAge(Person* this, int a) {

    this->age = a;

}

C++继承

继承:子类(派生类)复用父类(基类)的成员,形成 “is-a” 的关系。

{

注解:

is-a 表示“X 是一种 Y”。

is-a 的本质:子类“属于”父类这个大分类、子类对象可以隐式转换为父类对象指针 / 引用、      子类对象前半部分布局 == 父类布局(子类对象开头就是父类对象,这就是指针兼容性的硬逻辑依据)

}

如果想要运行时多态,继承是必要前提。

继承的三种访问控制

继承方式

父类 public 成员

父类 protected 成员

父类 private 成员

public

保持 public

变成 protected

访问不到

protected

变成 protected

变成 protected

访问不到

private

变成 private

变成 private

访问不到

子类对象的内存模型

class Base {

    int a;

};

class Derived : public Base {

    int b;

};

对象内存布局:

Derived 对象:

[ Base::a ][ Derived::b ],父类成员在子类对象中有“物理存在”!这就是为什么子类对象可以当父类对象用(对象模型兼容性)。

this 指针与继承

Derived d;

d.breathe();

内部等价于:

Animal::breathe(&d);  // this 指向 Derived 对象,但用父类部分去访问

this 指针可以自动向上转为父类类型。这也是为什么多态里 virtual 必须基于指针或引用。

底层实现:对象布局与虚表

普通继承:没有虚表,仅通过偏移访问成员。

Derived d;

Base* p = &d;

p->breathe();  // 编译期已确定,直接偏移访问成员

多态(virtual 函数):

编译器在对象头部插入 vptr(虚表指针):

Derived 对象:

[ vptr ][ Base::a ][ Derived::b ]

vptr 指向 vtable(虚表),vtable 记录所有虚函数地址

C++多态

概念

多态(Polymorphism):同一个接口,不同对象有不同表现。

用统一的父类指针 / 引用,调用不同子类的实现。

动态绑定:运行时决定调用哪一个函数(虚函数机制)。

多态 = vptr 指向 vtable,运行时根据对象真实类型查表找函数

class Animal {

public:

    virtual void speak() { std::cout << "Animal speaks" << std::endl; }

};

class Dog : public Animal {

public:

    void speak() override { std::cout << "Dog barks" << std::endl; }

};

Animal* p = new Dog();

p->speak();   // 输出:Dog barks

如果没有 virtual,输出就永远是 Animal speaks。

静态绑定vs动态绑定

类型

绑定时间

依赖条件

效果

静态绑定

编译期

成员函数(非虚函数)

快,无灵活性

动态绑定

运行期

虚函数 + 指针 / 引用

灵活,代价更高

为什么用指针 / 引用?

只有指针 / 引用才能脱离对象实际类型,让编译器 defer 到运行时决定实际类型。

底层实现原理

本质:虚表(vtable+ 虚表指针(vptr

步骤:

1.编译器生成 vtable

类名

vtable 内容

Animal

&Animal::speak

Dog

&Dog::speak

2. 对象布局插入 vptr

Dog d;

[ vptr -> Dog::vtable ]

[ Animal::成员 ]

[ Dog::成员 ]

3. 调用过程拆解

p->speak();

调用过程等价于

(*(p->vptr)[0])(p);

图解结构:

Dog 对象:

┌──────────┐

vptr ─────────┐

└──────────┘   

               

          ┌────────────┐

          vtable    

          ───────   

          speak ──┐ 

          └────────┬┘ 

                     

                     

               ┌───┴───┴────────────┐

               void Dog::speak()  

               └────────────────────┘

this 指针与多态的结合

void Dog::speak() {

    std::cout << "Dog says, this->type = " << this->type << std::endl;

}

本质:

void speak(Dog* this) {

    ...

}

虚表继承规则

行为

结果

子类未重写虚函数

继承父类 vtable 项

子类重写虚函数

重写覆盖 vtable 对应项

子类新增虚函数

vtable 追加新项

虚表多态 vs 非虚函数

场景

调用行为

非虚函数(静态绑定)

直接根据类型偏移确定地址

虚函数(动态绑定)

运行时查 vtable 决定地址

多态的条件总结

必须条件

理由

虚函数

没有虚表就没有动态绑定

指针 / 引用

否则编译期已确定类型

派生类重写

否则子类不会改变行为

额外知识:vptr 位置

编译器

vptr 插入位置

MSVC

对象头部第一个字节

GCC

对象头部第一个成员位置(隐式)

多态的核心底层模型总结

多态成立条件

底层逻辑

有虚函数

产生虚表,vptr 指向

指针 / 引用

通过 vptr 查虚表调用

重写函数

更新虚表中的函数地址

易错与误解总结

错误理解

正确理解

虚表存在于类

vtable 存在于类,vptr 存在对象

子类一定有新表

没有重写就共享父类表

无指针也有多态

多态只有指针 / 引用才有效

示例:

#include <iostream>

using namespace std;

// -----------  父类 -----------

class Animal {

public:

    string name = "Animal";

    virtual void speak() {  // 虚函数,多态基础

        cout << "Animal speaks!" << endl;

    }

    void breathe() {        // 非虚函数

        cout << "Animal breathes." << endl;

    }

};

// -----------  子类 -----------

class Dog : public Animal {

public:

    string breed = "Bulldog";

    void speak() override {   // 重写虚函数

        cout << "Dog barks!" << endl;

    }

    void fetch() {

        cout << "Dog fetches!" << endl;

    }

};

// -----------  使用父类指针演示多态 -----------

void animalSpeak(Animal* a) {

    a->speak();    // 多态,运行时动态绑定

    a->breathe();  // 非虚函数,静态绑定

}

int main() {

    Dog d;

    cout << "直接调用子类对象:" << endl;

    d.speak();    // Dog::speak,静态绑定

    d.breathe();  // Animal::breathe,静态绑定

    d.fetch();    // Dog::fetch,静态绑定

    cout << "----------" << endl;

    cout << "父类指针指向子类对象,演示多态:" << endl;

    Animal* p = &d;

    p->speak();    // 动态绑定 -> Dog::speak

    p->breathe();  // 静态绑定 -> Animal::breathe

    cout << "----------" << endl;

    cout << "通过统一接口调用:" << endl;

    animalSpeak(&d);

}

输出:

直接调用子类对象:

Dog barks!

Animal breathes.

Dog fetches!

----------

父类指针指向子类对象,演示多态:

Dog barks!

Animal breathes.

----------

通过统一接口调用:

Dog barks!

Animal breathes.

http://www.dtcms.com/wzjs/284355.html

相关文章:

  • 做企业网站需要注意什么渠道销售怎么找客户
  • 做动图的网站知乎电子商务营销
  • 广州网站建设一般多少钱百度搜索风云榜排名
  • 网站建设的时候如何上传图片网易企业邮箱
  • 许昌知名网站建设价格收录查询工具
  • 连云港做网站公司哪家好中国国家培训网
  • 深圳专业网站制作费用搜索引擎优化免费
  • 手机访问网站建设中seo系统培训哪家好
  • 有没有个人做网站的免费个人推广引流平台
  • html做网站的代码企业新网站seo推广
  • 查看WordPress网站插件百度站长工具综合查询
  • 做网站广告有哪些职位中国教师教育培训网
  • 惠州网站建设培训外贸网络推广公司
  • 石家庄做网站备案有哪些公司宁波的网络营销服务公司
  • 怎么做国外网站百度经验手机版官网
  • 自己的网站怎么做app吗百度seo关键词排名 s
  • 网站建设申请武汉seo工作室
  • 本地网站建设视频平台推广费用一般是多少
  • 天津市建设安全协会网站上海seo网站推广
  • 吉县网站建设百度app怎么找人工客服
  • 设计师导航网站广州seo排名外包
  • 昆明学校网站建设网站优化排名软件网站
  • 校园微网站界面如何做公司网站推广
  • 网站的二级栏目怎么做上海专业网络推广公司
  • 房地产网站策划建站官网
  • 小企业网站如何建设好bing搜索引擎入口
  • 学校网站建设企业线上推广方案怎么做
  • 安徽省铜陵市建设银行网站网站排名优化专业定制
  • bluehost空间内直接安装wordpress失败seo行业网
  • 高端网页开发宁波seo快速优化