
C++对象模型_读书笔记
文章平均质量分 64
Virtual_Func
小风扇吹风好吵
展开
-
4.1 成员函数的各种调用方式(静态成员函数,非静态成员函数,虚拟成员函数)
Q1:成员函数分为三种:静态成员函数,非静态成员函数,虚拟成员函数。本节的讨论均使用以下的类例子:Eg: class Point3d { public: Point3d(int i = 0, int j = 0, int k = 0) :_x(i), _y(j), _z(k){} Point3d norma原创 2015-07-22 11:41:14 · 1200 阅读 · 0 评论 -
6.3 临时对象
Q1:讨论一下三种语句产生临时对象的情况 //1. T c = a + b; //2. c = a + b; //3. a + b;对第一种情况,实现时不会产生临时对象,可能会直接以拷贝构造的情况,将 a + b 的值放入 c 中,或是直接进行NRV优化,导致直接在对象 c 中求值操作以下讨论另外两种情况Q2:对 c =原创 2015-08-29 11:51:15 · 448 阅读 · 0 评论 -
4.2 虚拟成员函数
Q1:C++多态形式:静态多态性、动态多态性• 多态:以一个 “public base class” 的指针寻址出一个 “derived class object”(深入探索C++对象模型定义)• 静态多态性通常称为编译时多态,到底模板是不是多态???我个人认为不是• 动态多态性通常称为运行时多态,通过虚函数来实现• 动态多态性的两个条件:○ 在基类中必须使用虚函数或纯虚函数○ 调用函数时使用基类的原创 2015-08-14 18:44:07 · 724 阅读 · 0 评论 -
4.5 内联函数
Q1:inline关键字• 关于 inline 请求是否被接收• inline 关键字是一项请求,如果这项请求被接收,编译器就必须认为它可以用一个表达式合理的将这个函数扩展开。• 这种合理性体现在:这个内联函数的执行成本比一般的函数调用以及返回机制所带来的负荷低(编译器内部存在衡量方法)• 处理一个 inline 函数有两个阶段分析函数定义,以决定函数的“instrisic inline abil原创 2015-08-16 16:57:40 · 520 阅读 · 0 评论 -
4.4 指向成员函数的指针
Q1:非静态成员函数的地址• 非静态成员函数地址值:○ 如果该函数是非虚函数,则得到的结果是其在内存中真正的地址○ 如果该函数是虚函数,则得到的结果是其在虚函数表中的索引值• 地址不完全性(数据成员的地址与函数成员的地址):○ 非静态数据成员的地址是其在类的布局中的位置(加1),是一个不完整的值,需要将其绑定在一个类对象上,才能进行存取○ 非静态函数成员(非虚)的地址是其在内存中的真正地址,但仍是原创 2015-08-16 16:03:13 · 750 阅读 · 0 评论 -
7.2 异常处理
Q1:编译器的任务• 支持异常处理,编译器的主要工作是找到 catch 子句,以处理被抛出的异常。需要支持以下几个工作:• 追踪程序堆栈中每一个函数的目前作用区域(包括追踪函数中局部类对象当时的情况)• 提供某种查询异常对象的方法,以知道其实际类型• 管理被抛出对象的机制,包括其产生,存储以及析构Q2:异常处理知识点回顾• 当异常被抛出时,控制权将从函数调用中释放出来,并寻找一个吻合的 catch原创 2015-08-31 17:56:42 · 465 阅读 · 0 评论 -
7.3 执行期类型识别(Runtime Type Identification,RTTI)
Q1:保证安全的基类到派生类的向下转换操作• 支持安全的类型转换对多态类而言,需要在执行期判断指针所指对象的真实类型,因此,会引入额外的空间与时间开销: ○ 空间开销:存储类型信息,通常是一个指针,指向某个类型信息的节点(该指针放置在虚函数表的第一个表项中) ○ 时间开销:在执行其决定其类型• 区别一个类是否具有多态性,是根据其是否内含虚函数来进行判断。(注:析构函数是唯一不能重载原创 2015-09-01 10:46:17 · 485 阅读 · 0 评论 -
5.1 无继承情况下的对象构造
Q1:POD对象的构造• 以下讨论围绕下述例子展开: Eg: struct point { float x, y, z; }; point global; int main() { point l原创 2015-08-19 16:19:56 · 602 阅读 · 0 评论 -
5.2 继承体系下的对象构造
Q1:在数据成员定义了三种构造成员函数与析构函数之一的情况下:*注:上述三个构造成员函数指:默认构造函数,复制构造函数,赋值操作符函数• 以下列例子进行讨论:Eg: class Point { public: Point(int i = 0, int j = 0) :x(i), y(j),{} Point(con原创 2015-08-21 13:17:07 · 593 阅读 · 0 评论 -
vector中不能存放引用类型!!!!!!!!
关于 vector 中不能存放引用,这是一个在初始C++时候就应该知道的问题,但是我居然没注意,还好及时发现了。《C++ primer》上说 vector 中不能存放引用的原因是:引用不支持一般意义上的赋值操作,而 vector中元素的两个要求是:1.元素必须能赋值2.元素必须能复制int a = 1;int c = 2;int & b = a;b = c;原创 2015-11-08 23:06:20 · 14221 阅读 · 0 评论 -
详解RVO与NRVO(区别于网上常见的RVO)
一直以来对 RVO 与 NRVO 以及编译器的优化操作之间的关系都不太分得清。这一次想了两天,查看了若干资料以后,总算弄清楚了。1.RVO(Return Value Optimization)先来看一下维基百科上对RVO(return value optimization) 的定义:"Return value optimization, or simply RVO, is原创 2015-09-24 13:29:48 · 12911 阅读 · 0 评论 -
3.5 指向类成员的指针知识点
<1> 指向类成员的指针给出的是该类成员在类中的偏移量,而不是真正的地址。即假设:Eg:class A { public: int val; }; //此时有: &A::val; //得到的是类成员 val 在类中的偏移量,若 vptr 在对象尾部,则该值为1(或0) A原创 2015-07-21 11:57:42 · 414 阅读 · 0 评论 -
3.4 继承与数据成员内存布局
Q1:具体继承(单一继承)且无多态的情况• 具体继承(对应于虚拟继承)并不会增加空间或存取时间上的额外负担• 在这种情况下,类对象的内存存储情况如下:Eg: class X { int x; char c; }; class Y : public原创 2015-07-20 18:33:33 · 589 阅读 · 0 评论 -
1.2 关键词带来的差异,class 与 struct
struct 与 class 的实际区别与使用区别原创 2015-07-16 22:02:02 · 801 阅读 · 0 评论 -
2.1 默认构造函数的构造操作
默认构造函数的合成,类成员的初始化原创 2015-07-16 22:44:38 · 580 阅读 · 0 评论 -
6.1 对象的构造与析构
Q1:对象的构造函数与析构函数的分布• 对象在被创建时就会调用其构造函数 ,若在一个区段中有一个以上的离开点,则析构函数必须放在每个离开点前Eg: { Point point; //构造函数调用 switch(int(point.x)) { case -1 : //析构原创 2015-08-25 14:51:18 · 689 阅读 · 0 评论 -
2.4 成员初始化列表
构造函数初始化列表原创 2015-07-16 22:59:47 · 476 阅读 · 0 评论 -
2.2 复制构造函数的构造操作
复制构造函数复制构造函数的调用逐位拷贝语义学原创 2015-07-16 22:54:06 · 537 阅读 · 0 评论 -
1.3 编程范式
编程范式,面向过程模型(OB),抽象数据类型模型(ADT),面向对象模型(OO)原创 2015-07-16 22:28:44 · 681 阅读 · 0 评论 -
1.1 对象模型
C++数据成员分类,虚继承,对象模型原创 2015-07-16 21:49:17 · 361 阅读 · 0 评论 -
3.1 、3.2 数据成员的绑定与布局
Q1:关于类成员函数中的变量与类数据成员、全局数据之间的绑定关系• 一个 inline 函数实体,在整个类声明未被完全看见之前,是不会被编译器分析的• 该延迟规则对参数列表中的类型名称不起作用,类型名称之前的绑定会在遇见时进行决议(* 重点 *)Eg:typedef int length;int _val = 10;class X{public: X(float a = 0.0) :_va原创 2015-07-20 12:02:20 · 527 阅读 · 0 评论 -
3.3 数据成员的存取
本节的讨论针对两种情况的效率进行分析:class X{ public: //数据成员mem static double mem;};X orgin;X * pt = &orgin;//考虑以下两种情况各自的存取效率orgin.mem = 0.0; //case1pt->mem = 0.0; //case2Q1:mem是静态数据成员• 每个静态数原创 2015-07-20 12:06:18 · 449 阅读 · 0 评论 -
6.2 new 和 delete 运算符
Q1:new运算符• new运算符是由两个步骤组成1. 通过适当的new运算符函数的实例,配置所需要的内存2. 给配置得来的对象设立初值Eg: int * pt = new int(5); //实际操作如下: int * pt; if(pt = _new(sizeof(int))) *pi = 5; //通过构造原创 2015-08-26 12:10:46 · 783 阅读 · 0 评论 -
3.空类的sizeof
Q1:关于继承类大小与空类大小• 一个空类,无基类,其大小为1 :对空类而言,其中含有编译器安插进去的一个 char ,这使的这个类的两个对象得以在内存中配置独一无二的地址• 一个空类,继承自一个空基类,其大小为1 :其基类的大小占1个字节,而其本身并不占空间,通过其基类子对象的独一无二性来体现其本身的独一无二性• 一个空类,继承自一个空的虚基类,其大小分两种情况:1) 提供优化处理,其大小为4:空原创 2015-07-20 11:58:35 · 611 阅读 · 0 评论 -
关于指针与类的内存分布问题(问题思考来自《程序员面试宝典》)
引起思考的例子:class A{public: int a_1,a_2; A() :a_1(1),a_2(2){} void func() { cout << a_1 << endl; cout << a_2 << endl; }};class B {public: int b; B() :b(3){} void func() { cout <<原创 2016-03-29 14:57:14 · 613 阅读 · 0 评论