《深度探索C++对象模型》第1章重点:关于对象

c++对象模型的设计:nonstatic的data members被放置于每一个class之内,static的data members则被放置于class之外,static和nonstatic的function被放置于class之外。virtual function以下面两个步骤支持:

  1. 每个class产生一个virtual table(vtbl),里面存放指向每个virtual function的指针。
  2. 每一个class对象有一个指针vptr,指向相关的vtbl,vptr的设定和重置由每个class的构造函数、析构函数和copy assignment运算符自动完成。vtbl的第一个slot通常放的是这个class的type_info object指针,用以支持runtime type identification,RTTI

static变量存放于全局变量区(.data),是为符合static语义,其需要在类外进行初始化,分配内存,因为它的生命周期是全局,而class对象的生命周期在它被定义之后才开始。

c++中class和struct的差异:struct可以干class的所有事情,只是struct的默认成员访问权限为public,class的默认成员访问权限为private;struct默认是公有继承,class默认是私有继承;当struct和class中没有构造函数且成员变量(无需成员函数)全为public时,可以用{}进行初始化。

struct适合看成是一个数据的集合体;class适合看成一个对象。

c++以下列方法支持多态:

  1. 经由一组隐式的转化操作,例如将派生类指针转化为一个指向其基类的指针:

    Shape *ps = new Circle();

  2. 经由virtual function机制:

    ps -> rotate();

  3.经由dynamic_cast和typeid运算符

    if(Circle *pc = dynamic_cast<Circle*>(ps)) ...

typeid本质上即是通过虚函数表的第一个slot内的指针所指向的type_info object来判断是哪种class

多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常定义在基类中,并在不同的派生类中有不同的实现。通过virtual function机制在运行时才确定到底调用哪个函数实例。

void rotate(X datum, const X *pointer, const X& reference) {
    //下面这个操作总是调用X::rotate(),因为datum的类型已经确定,不走虚函数表的方式;
    datum.rotate();
    //下面这两个操作必须在运行期才能知道调用的是那个rotate()实例
    (*pointer).rotate();
    reference.rotate();
}
main() {
    Z z; //Z是X的一个子类型
    rotate(z, &z, z);
    return 0;
}

不同类型指针的差别:只在其所寻址出来的object类型不同,“指针类型”会教导编译器如何解释某个特定地址的内存内容及大小。一个类型为void*的指针只能够持有一个地址,而不能通过它操作所指的object。

Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;

pz和pb都指向Bear object的第一个byte,其间差别:pb所涵盖的地址包含整个Bear object,而pz所涵盖的地址只包含Bear object中的zooAnimal部分。

Bear b;
ZooAnimal za = b; //引起切割,事实上会调用拷贝构造函数,设定正确的vptr
za.rotate(); //调用ZooAnimal::rotate(),在编译器就已经确定

一个指针或者引用之所以支持多态,是因为它们不引发内存中与类型相关的改变,而只改变它们所指向内存的“大小和内容解释方式”。

原文地址:https://www.cnblogs.com/senshaw/p/10944439.html

时间: 2024-10-18 10:54:49

《深度探索C++对象模型》第1章重点:关于对象的相关文章

深度探索C++对象模型之第一章:关于对象之对象的差异

C++程序设计模型支持三种程序设计范式(programming paradiams). 程序模型(procedural model) char boy[] = "ccpang"; char *p_son; p_son = new char[strlen(boy) +1 ]; strcpy(p_son,boy); if(!strcmp(p_son,boy)) take_to_disneyland(boy); 抽象数据模型(abstract data type model) 此模型的抽象是

【深度探索C++对象模型】第二章 构造函数语意学(上)

第二章 构造函数语意学(The Semantics of Constructors) -- 本书作者:Stanley B.Lippman 一.前言 首先让我们来梳理一个概念: 默认构造函数(Default Constructor) : 是在没有显示提供初始化式时调用的构造函数.它由不带任何参数的构造函数,或是为所有形参提供默认实参的构造函数定义.如果定义的某个类的成员变量没有提供显示的初始化式时,就会调用默认构造函数(Default Contructor). 如果用户的类里面,没有显示的定义任何

【深度探索C++对象模型】第一章 关于对象

第一章 关于对象(Object Lessons) -- 本书作者:Stanley B.Lippman 一.前言 什么是 C++ 对象模型:简单的说,就是 C++ 中面向对象的底层实现机制. 本书组织: 第 1 章,关于对象(Object Lessons),介绍 C++ 对象的基础概念,给读者一个粗略的了解. 第 2 章,构造函数语意学(The Semantics of Constructors),构造函数什么时候会被编译器合成?它给我们的程序效率带来了怎样的影响? 第 3 章,Data语意学(T

深度探索C++对象模型 第三章 Data 语意学

一个有趣的问题:下列 类 sizeof大小 class X{}    //1 class Y:public virtual X{} //4 or 8 class Z:public virtual X{} // 4 or 8 class A:public Y,public Z{} // 8 or 12 主要原因:为了保持每一个类生成对象在内存中的唯一性,编译器必须要给空类生成一个char来维持object的唯一性: 而virtual继承中,仅保持了base class的指针,有些编译器会继承bas

深度探索C++对象模型 第五章 构造、析构、拷贝语意学

1. const 成员函数需要吗? 尽量不要,如果存在继承,则无法预支子类是否有可能改变data member 2. pure virtual constructor 可以实现类的隐藏吗(包含data member)?   这样子类无法调用base 的构造函数对数据初始化,所以可以用protected来实现构造函数,可以实现子类调用: 3. 如果class中存在virtual function,则编译器会再构造函数中对vptr进行初始化(在base构造函数调用之后,而代码实现之前) 4.拷贝构造

深度探索C++对象模型第6章 执行期语意学

(一)对象的构造和析构(Object Construction and Destruction) 一般而言我们会把object尽可能放置在使用它的那个程序区段附近,这么做可以节省非必要的对象产生操作和摧毁操作. 全局对象 如果我们有以下程序片段: Matrix identity main() { //identity 必须在此处被初始化 Matrix m1=identity; ... return 0; } C++保证,一定会在main()函数中第一次用到identity之前,把identity

《深度探索C++对象模型》第二章 | 构造函数语意学

默认构造函数的构建操作 默认构造函数在需要的时候被编译器合成出来.这里"在需要的时候"指的是编译器需要的时候. 带有默认构造函数的成员对象 如果一个类没有任何构造函数,但是它包含一个成员对象,该成员对象拥有默认构造函数,那么这个类的隐式默认构造函数就是非平凡的,编译器需要为该类合成默认构造函数.为了避免合成出多个默认构造函数,编译器会把合成的默认构造函数.拷贝构造函数.析构函数和赋值拷贝操作符都以内联的方式完成.一个内联含有具有静态链接,不会被文件以外者看到.如果函数不适合做成内联,就

深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作

C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的设定“class内每一个data member的默认值” 一.编译器在哪种情况下才会合成默认构造函数: 对于未声明构造函数的类,只有在以下四种情况下编译器才会为它们合成默认构造函数: 类的成员有一个类对象(Member Class Object),且该成员含有默认构造函数(default Const

深度探索C++对象模型 第二章构造函数语意学

在使用C++时,常常会好奇或者抱怨,编译器为我们做了什么事呢? 为什么构造函数没有为我初始化呢?为什么我还要写默认构造函数呢? 2.1 Default Constructor 的构造操作 如果没有声明默认构造函数,编译器会在需要的时候帮我们产生出来. 为了避免在多个地方被需要导致重复,则编译器将产生的构造函数声明为inline方式. class Foo {public:Foo(), Foo(int) }; class Bar {public: Foo foo;char *str;} Bar ba

深度探索C++对象模型

著:Stanley B. Lippman  侯捷译  Inside the C++ Object Model 第一章:关于对象(Object Lessons) C++对象模型,了解到也是一个演变的过程,C++对象中包含了以下内容:(data members) non-static data,static data(const),以及(member functions):static,non-static,virtual 发展的主要过程主要集中于如何存储data 和 function,寻求时间和空