zoukankan      html  css  js  c++  java
  • 侯捷C++八部曲:C++面向对象程序设计

    1. C++编程简介

     

     

     

     

     

     

     

     2.头文件与类的声明

    c语言的数据暴漏的太多,任何函数都能访问,不容易维护

    类分两种,内部带指针的和不带指针的

     

     类里有指针要非常小心

     

     .h和.cpp是一部分,因为角色的区分,分成两部分

    自己的头文件用双引号,库的用尖括号

     可以把.h拿掉,c的stdio要写成cstdio

     

     

     

    3. 构造函数

     

     private:主要作用是要封装起来内部细节

    访问级别可以任意交错

     创建对象的时候构造函数自动被调用。不需要返回值,因为不需要自己创建本对象。初始化列表构造函数独有。数值设定分两阶段,用初始化和赋值,先初始化再复制。初始化列表属于初始化,构造函数体是赋值

    初始化列表的使用显得大气上档次

    不带指针的类,多半不用写析构函数

     

     重载是给函数改名

    构造函数一个是有默认参数,一个是没有参数,这样不行,两者冲突,因为编译器不知道选哪个函数,结果不唯一

    c1和c2()这两种方式创建对象都可以

     4.参数传递与返回值

     

     

     

     函数在参数和body之间加const,代表函数不会改变对象内容

    const对象调用非const方法会报错

    不改值的函数用const修饰是个好习惯

     尽量不要pass by value,复制浪费时间、空间。引用像指针但是更漂亮,使用更自然。引用、指针一般更快、更省空间,但和小字节数据比还是差

    按值传递是复制参数,改了参数也不会改原值,引用为了达到这种效果,要用const在变量类型前修饰,这样确保不会改变实参

     返回引用效率更高,返回值尽量是reference,有的情况不能返回ref

     友元比用函数拿效率高点,但是打破了封装

     

    正规写法:

    1.数据放private

    2.参数尽可能以reference来传,根据要不要改实参决定要不要带const

    3.返回值尽量以reference来传

    4.在类本体里定义的函数,不改值的加const

    5.构造函数用初始化列表初始化

    返回reference:返回的是一个本来就有的东西,不会有错。local对象就不能做为reference返回

    reference主要用在传递东西上

    5. 操作符重载与临时对象

     

     编译器自动把c2地址传进来当成this,this是函数的隐藏参数

    返回的是引用,接收端怎么接收不用在乎,用引用和value接收都可以,方便书写,只是效率有差别。传回指针就不行了,必须用指针接收,无法连着用。如果不加引用返回一个已存在对象,相应的会生成一个临时对象,构造、拷贝、析构分别来一次(造一个对象,要不用来常量引用要不用来拷贝,对左值修改影响不了原值,引用直接编译报错;NRVO可以优化不生成对象,直接走拷贝,效率一致,但NRVO可能失效),引用则是指针赋值或者拷贝一次。返回临时对象少复制一次只有一次构造,有编译器优化(RVO)

     重载只有一个能符合,多了编译器报错

    多个参数,顺序不定,用全局的容易掌控

    参数没有this pointer

    临时对象,没有名字,声明在下一行已经结束了 

    运算符 全局重载,靠参数个数确定函数名.只有一个参数放对象左边的,可以设计为全局函数也可以设计为类函数,运算符重载函数的结合性和默认的是一样的

     

    有些类不能修改,要用全局运算符重载其运算符

    不是自己写的,参数别加const

    6.复习Complex类的实现过程

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    7. 三大函数:拷贝构造,拷贝复制,析构

     

     

     拷贝构造与拷贝赋值区别:一个是构造初始化一个是赋值,拷贝构造的对象之前不存在,所以与赋值构造处理不同,不用清理以前的垃圾

    默认的是按bit复制,没有指针、引用就够用

     

     s1()也会调用构造函数

     浅拷贝,内存泄漏和数据别名

    拷贝构造函数只是复制,不想改变外面对象,所以要const参数

     

     判断是否是自己,清空已有数据,拷贝新数据。给已有对象重新赋值

     

     

     

     没有自我赋值检测,一是慢,二是产生悬垂指针

     

    8,堆、栈与内存管理

     对象的内存,要不位于栈区要不位于堆区

     析构函数自动被调用

     

    global对象构造函数早在main执行前就被调用

    类中的静态变量与全局变量相同。它的构造函数将在进入 main 函数之前被调用。

    • 结论(适用于 g++、Windows 环境):
    • 全局变量 类中的静态成员 : 在输入之前调用构造函数 功能 (1) .
    • 局部静态变量 : 构造函数仅在第一次执行到达其声明时调用。
    • 局部静态变量为 POD 类型 , 那么在输入 之前也是初始化的主 功能 (1) .
      POD 类型示例:static int number = 10;

    (1) :正确的状态应该是:“在调用来自同一翻译单元的任何函数之前”。但是,为了简单,如下例所示,它是主要功能。

     

     内存泄漏:没机会再delete堆上对象了,失去了控制

    "operator new",函数名就叫这个

     删除两块堆上的内存

     上下红色cookie用于记录整块大小,方便回收

    最后一位,0x41, 1用来表示已分配不可用,0用来表示可用未分配。最后一位可以借位是因为地址一定是16的倍数,所以最后一位必为零

     数组个数排在数据前面

    这里指针对象、数组指针还是指向对象内存地址的,而不是cookie等附加数据,相应的delete函数会自己去找

     写不写中括号不影响内存删除,但是影响析构函数调用,内存泄漏的是数据里的指针指向的堆内存。如果是复数类而不是字符串,加不加中括号都行

    9. 复习String类的实现过程

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    10.  扩展补充:类模板,函数模板,及其他

     

     静态成员数据是类只有一份,静态函数只能操作静态对象成员

    静态成员数据要在类外面初始化,不然编不过。

    这也叫静态成员的定义,定义会开内存空间。类里面的是声明而已,因为静态成员脱离于对象,是属于类的

     

     懒汉与饿汉模式区别

     

     

     template里typename和class相通

    类模板明确指出type,函数模板是根据参数自行推导

     namespace解决同名问题

     

    11. 组合与继承

     面向对象编程:类和类之间产生关系

     

     黑色菱形代表里面有东西

     

     编译器帮助调用部件的构造、析构。

    各自管各自的构造和析构即可,编译器全做好了

    如果调用默认的构造、析构不合适,就自己在初始化列表上调用组件的构造函数

     白色菱形是委托,用指针指向,有些虚

     二者寿命不一致

    pImpl模式:左边是接口,真正的实现在委托那里,方便实现变动、切换,这样就具有了弹性

    这种手法也叫做编译防火墙

    还有就是cow技术,改的时候才真正开辟新内存进行拷贝,不然就是复制一个指针

     白色三角形代表继承

     基类析构不是virtual,可能发生只调用基类析构不调用子类析构

    12. 虚函数与多态

    继承主要作用是要搭配虚函数,内存布局倒是其次

     函数的继承不应该从内存的角度理解,函数的继承继承的是调用权

     子类可以调用父类的函数

    形状很抽象,没什么东西就直接是形状,所以要定义有纯虚函数

    虚函数:希望子类来做,父类不做或者做的默认实现比较简单

     

     关键动作延缓到子类去做,叫做template method

     本质是虚函数通过vptr来调用,看是this指针是哪个对象就调到哪个函数

     既有基类又有Component,先调用基类构造函数

    13. 委托相关设计

     

    组合模式:容器可以容纳单体及容器

    C++容器里要放指针,因为必须一样大小,放对象可能基类、子类不一样大

     原型模式:应对未来之对象,要求其继承已有对象,用静态对象创建自己,构造函数里将其add进框架,框架提供虚函数,子类实现copy子类自己创造的东西

    LSAT:带下划线,是静态的,所以类自己创造了自己

    类图先写名字再写类型

    -代表private,#代表protected

    通过存储的指针调用相应类的clone方法,clone里调用protected构造函数防止调用私有的构造函数又注册一次

    框架应有之意:实现框架预置的方法,框架先写好了又要让他知道自己

     

     

     

  • 相关阅读:
    UWP 应用获取各类系统、用户信息 (1)
    Windows Composition API 指南
    详解 UWP (通用 Windows 平台) 中的两种 HttpClient API
    Win2D 官方文章系列翻译
    Spring的IOC容器, AOP切面及启动流程简述
    maven和gradle的全局阿里云镜像代理
    SpringBoot项目中@Async方法没有执行的问题分析
    Oracle向MySQL迁移的注意点整理
    SpringBoot项目替换内部的依赖jar包
    MySQL的主从复制
  • 原文地址:https://www.cnblogs.com/cascle/p/15586692.html
Copyright © 2011-2022 走看看