第1章 关于对象
00 min
2023-12-24
2025-2-18
type
status
date
slug
summary
tags
category
icon
password

第1章 关于对象

在C语言中,“数据”和“处理数据的操作”是分开来声明的,也就是说C语言本身不支持数据和函数之间的关联性。而在C++中,编程语言本身就支持数据和函数封装在一起,并且这种封装并不会造成空间和时间上的不良后果。C++在布局和存取时间上的额外负担主要是由virtual引起的,包括
  • virtual function机制
  • virtual base class
  • 多重继承下的额外开销

1.1 C++对象模式

C++中有两种数据成员:静态变量和非静态变量
三种成员函数:静态函数、非静态函数以及虚函数

C++对象模型

最简单的思路就是在每个对象实例里面都存储指向数据和函数成员的指针,这样的模型大大降低了C++编译器的设计复杂度,但是大量存储空间都被浪费。
C++对象模型是从简单对象模型派生而来的,在这个模型中,每个对象实例中都拥有非静态成员变量,但是静态成员变量、静态成员函数以及非静态成员函数都放在单个对象实例之外
对于虚函数来说,主要通过虚表和虚表指针来实现虚函数。
  1. 每一个类都会有一个虚表,这个表格包括这个类的类型信息(用于运行状态识别 RTTI)以及指向虚函数的指针
  1. 每一个类实例都有一个虚表指针,然后这个指针指向虚表。这个虚表指针的设定和重置由每一个类的构造、析构、复制赋值自动完成
notion image
这个模型对内存空间和存取空间做了优化,但是类的非静态成员变量有所修改的话,那么程序代码就必须重新编译
 

1.2 struct关键词的困扰

struct

 
struct 和 class的差异
因为struct是一种数据类型,那么就肯定不能定义函数,所以在面向c的过程中,struct不能包含任何函数。否则编译器会报错 面向过程的编程认为,数据和数据操作是分开的。然而当struct进入面向对象的c++时,其特性也有了新发展,就拿上面的错误函数来说,在c++中就能运行,因为在c++中认为数据和数据对象是一个整体,不应该分开,这就是struct在c和c++两个时代的差别。
  1. 默认的继承访问权。class默认的是private,strcut默认的是public。
  1. 默认访问权限:struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。
  1. “class”这个关键字还用于定义模板参数,就像“typename”。但关建字“struct”不用于定义模板参数
  1. class和struct在使用大括号{ }上的区别 关于使用大括号初始化
    1. 1.)class和struct如果定义了构造函数的话,都不能用大括号进行初始化 2.)如果没有定义构造函数,struct可以用大括号初始化。 3.)如果没有定义构造函数,且所有成员变量全是public的话,class可以用大括号初始化

1.3 对象的差异

 
 
C++ 以下列方式支持多态
  • 隐式转化,把一个子类指针转化为父类指针
  • 经由虚函数机制,调用虚函数
  • 经由dynamic_cast和typeid运算符
 
一个class object的内存
  • non-static data members 的总和大小
  • 内存对齐的需求
  • 为了支持virtual产生的内存
 

指针的类型

不同类型的指针,在内存需求上没有什么不同,因为在同一机器上不同指针的所占内存是固定的。他们的不同,主要在于所寻址出来的object类型不同,也就是说,指针类型会教导编译器如何解释某个特定地址中的内存内容及其大小。
那么对于一个void* 指针来说,将涵盖怎样的地址空间,是未知的。因此一个类型为void*的指针只能够持有一个地址,而不能通过他操作所指向的object。
所以cast其实是一种编译器指令,大部分情况下,它并不会改变一个指针所含的真正地址,他只影响编译器对指针的解释方式
 

加上多态之后

 
当在C++中定义类时,类的类型在编译时期确定两个关键点:
  1. 固定的可用接口:类定义了一组函数或方法,这些函数构成了类的接口。这些接口在编译时期被固定下来,无法在运行时修改。其他代码可以使用这些接口来与对象进行交互,而不必了解对象的内部实现细节。
  1. 接口的访问级别:类中的成员函数和变量可以具有不同的访问级别,如公有(public)、私有(private)和受保护(protected)。这些访问级别决定了哪些部分的类可以被外部代码访问。这个决定也在编译时期进行,以确保在程序执行时的可靠性和安全性。
 
  • 指针或者引用支持多态,是因为他们并不引发内存中任何与类型有关的内存委托操作,会受到改变的只有他们指向内存的大小和内容解释方式而已。
 
 
 
 

参考

上一篇
C++ 对象模型
下一篇
Shallow Water Equations