美文网首页
GeekBand C++ week 2

GeekBand C++ week 2

作者: 龙曜 | 来源:发表于2016-10-17 21:12 被阅读19次

    1.String class (class with pointers)

    '=' 赋值方式实现指针copy

    copy构造(接受同类作为初值)和 copy赋值(赋值右操作数是同类)不写的话也存在,每bit复制(编译器提供的)。

    数据是一个指针,需要时再动态分配空间

    接口:构造函数对不同输入操作符重载

    析构函数:~+class name, 当一个类对象结束生命时调用(即程序执行离开作用域时)

    Big Three: copy构造、copy赋值、析构函数

    2.ctor和dtor(构造函数 和 析构函数)

    new/delete == malloc()/free() 内存泄漏 动态分配而不释放相应内存

    注:“hello”作为初值并不内含'\0',应在初始化时增加

    3.class with pointer members必须有copy ctor和copy op=

    如果使用default copy ctor或default op=是浅copy,只修改指针的值(因为字符串实际存储位置并不在对象内,使得内存泄露,而内存中仍只有一份数据副本) 出现alias(叠名,多名称指向同一内存空间很危险)

    深copy,清除原来的无用数据空间 ,分配新的存储空间,来建立副本。

    在copy op=时,注意检查自我赋值(小心alias,提高效率,防止副本在复制前被删除,产生未知bug)

    复习 为了避免重载‘<<'时改变方向,要声明为全局函数,以免对象默认作用于左值, ostream要作为左值。

    4.Stack(栈)&Heap(堆) scope(作用域)

    Stack是存在于某作用域(scope)的一块内存空间会形成一个stack以放置它所接收的参数,local(auto) object,以及返回地址

    Heap,或system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从某中获得若干区块(blocks)

    5.objects的生命期 何时调用相应析构函数

    stack(auto) 在作用域结束之际结束;

    static local objects 在整个程序结束时结束;

    global objects 在整个程序结束时结束,可视为一种特殊的static object;

    heap objects 在它被deleted之际结束。

    6.new 先分配memory,再调用ctor

    void *mem = operator new(sizeof(type)); //分配内存 内部调用malloc(n)

    pc = static_cast(mem); //类型转换

    pc->type::type(arg); //构造函数 => Complex::Complex(pc, 1, 2) pc是ctor作为成员函数的this指针

    7.delete 先调用dtor,再释放memory

    type::~type(pc); //析构函数

    opetator delete(pc); //释放内存

    8、动态分配所得的内存块(memory block)

    (system)cookie +(Debug header 32bytes+) 所需内存 + (no man land 4 +)(pad 4*n +)(system)cookie

    cookie(4byte)以标志分配区块大小和状态

    因为VC中都为16的倍数,所以cookie最后一个byte的低四位总是0,因此可以用最低位借位表示1已分配和0未分配

    动态分配所得array(array new搭配array delete)

    (system)cookie +(Debug header 32bytes + )元素数标志(int 4byte) + 所需内存 + (no man land 4 +)(pad 4*n +)(system)cookie

    未搭配情况,会使得析构函数不正确调用,使得array内动态分配去泄露

    补充内容

    1)static 通过传入this pointer使得同一个成员函数处理不同的对象,而不会出现多个重复函数单一处理各自对象,静态函数没有this pointer只能处理静态数据。static数据全类唯一,并通过类外赋值完成初始化,初始化要在实现中进行。静态函数既可被对象作为成员函数调用,也可以作为类成员函数直接调用。

    静态函数和静态数据成员都不是对象成员而属于类的静态成员,静态成员访问可以在类中进行,对非静态成员则只能通过对象。

    singleton模式,以static方式(类中副本单一)

    2)cout 进行了大量的<<操作符的重载,一种ostream

    3)class template 对同一实现成员不同的情况进行代码重用 template 使用时:class

    function template 对同一实现成员不同的情况进行代码重用 template 使用时不必显式声明,编译器对function template可以进行参数推到(argument deduction)

    4)namespace + 名称,把所有用到的东西封装在一个namespace里,以免重名产生的错误。多文件写std在编译时会被组合到一起。

    使用方式

    using directive 将封装完全打开,e.g. using namespace std;

    using declaration 逐条声明 e.g. using std::cout;

    直接写出全名 e.g. std::cin >> ...;

    面向对象编程 探讨类和类之间的关系

    1.Inheritance(继承) is a关系

    三种继承方式

    :public 父类(Base)的数据是被子类(Derived)完整继承的,子类中含有父类的成分;和虚函数搭配体现价值;

    函数的继承继承的是调用权;在子类对象中调用父类函数是一种常见现象。把父类的强关联函数,放到具体子类中实现,建立Template Method实现。一般性操作建立Application framework,使专业人员能集中处理核心问题。成员函数内调用函数仍由this作为参数调用。

    构造由内而外:Derived::Derived(...): Base() {...};

    构造由外而内:Derived::~Derived(...) {...~Base() };

    base class 的dtor必须是virtual,否则会出现undefined behavior。

    :protected

    :private

    Inheritance(继承) with virtual functions(虚函数) override(仅用于虚函数被重新定义,覆写)

    non- virtual function: 你不希望derived class override它

    virtual function:你希望derived class override它,且你对它已有默认定义 virtual 标识符

    pure virtual function:你希望derived class一定要override它,你对它没有默认定义 virtual 函数声明 =0

    Inheritance + Composition 关系下的构造和析构

    //Derived 同时含有 Composition的component情况

    Derived::Derived(...):Base(), Component() {...} 构造由内而外

    Derived::~Derived(...):{...~Component(), ~Base()}; 析构由外而内

    Delegation + Inheritance 尤其用在user interface

    Subject(数据存储)-建立vector-> Observer(数据展示)

    多种展示方式作为Observer的子类。

    2.Composition(复合) has a关系,引用其它结构/类型作为成员。

    Adaptor:通过复合一个强功能的结构,然后开放部分功能(即构建一个adaptor),来使之符合使用要求。

    Container -> Component

    Container构造时由内而外,先调用Component的default构造函数,然后才执行自己;

    Container析构时由外而内,首先执行自己,然后才调用Component的析构函数。

    以上都是编译器补充的,实际构造析构并不需要明文写出。

    如果编译器提供的默认方式不合意,请自行编写构造函数。

    3.Delegation(委托)/Composition by reference

    用指针的方式实现has,而不是直接含有相应对象,需要时指针才有所指(不同步)。

    pointer to implementation/Handle & Body 用指针指向实现,可以方便的切换实现,亦称编译防火墙。

    reference counting 内容共享特性,特别注意,共享时修改要copy on write即修改时提供新的副本给对象进行修改。

    4.设计模式

    容器里放的东西一定要一样大小,因此推荐指针作为容器参量。add 以指向父类的指针进行操作,使得两种子类都可以进行add 操作。

    现在去创建未来的对象,每一个子类创建自己,被之前的父类看到,子类把自己的原型置入父类的相应空间。

    相关文章

      网友评论

          本文标题:GeekBand C++ week 2

          本文链接:https://www.haomeiwen.com/subject/pgjzyttx.html