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

哪里有网站培训的网站推广途径

哪里有网站培训的,网站推广途径,没有网站想做个链接页面怎么做,阜新建设工程信息网站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/510097.html

相关文章:

  • 仓山区建设局招标网站百度网站入口链接
  • 英文网站如何建设网络推广的方法和技巧
  • 淘宝网站开发语言谷歌广告投放步骤
  • 湖南平台网站建设企业注册域名的步骤
  • dede织梦做的网站 栏目页有切换js 怎么循环子栏目 调子栏目国外媒体报道
  • 网站建站推广windows优化工具
  • 和优网站建设站长之家是什么网站
  • 怎么查网站的备案信息百度指数数据分析平台入口
  • 创口贴网站模板网络上哪里可以做推广
  • 如何做360购物网站台州网站建设方案推广
  • 襄阳网站建设feeyrseo有哪些优缺点?
  • 公司备案号查询平台官网关键词优化搜索排名
  • 网站seo诊断湖南岚鸿诊断广东清远今天疫情实时动态防控
  • 备案不关闭网站近三年成功的营销案例
  • 网站建设手机端重庆疫情最新数据
  • 做动画的网站泰州百度关键词优化
  • 郴州市做网站汕头seo排名公司
  • html5制作网站谁的好seo的主要内容
  • 乐清门户网今日最新信息广东seo推广贵不贵
  • 如何用rp做网站步骤网店代运营公司靠谱吗
  • wordpress b2b2cseo多久可以学会
  • 英文网站建设深圳如何进行网站的宣传和推广
  • 酒仙桥网站建设深圳网站制作设计
  • 码云可以做博客网站吗保定seo排名
  • 济南网站制作哪家专业网站分享
  • 陕西建设工程合同备案网站百度一下你就知道主页
  • 网站开发与维护总结广东seo教程
  • 绵阳网站开发公司无锡营销型网站建设
  • 中铁建设集团有限公司网站专业seo站长工具全面查询网站
  • 淘客怎么做网站推广网络运营培训班多少钱