C++回顾(未完待续,长期更新)

OOP之类和对象

1. this指针的引入

每个成员函数都有一个额外的隐含的形参,这个参数就是this指针,它指向调用对象的地址。默认情况下,this的类型是指向类类型非常量版本的常量指针。可以表示成如下伪代码形式:

/* 假设现在有一个类Sales_data,以及其非常量Sales_data类型对象,则该隐式的this指针可以写成如下伪代码形式 */
Sales_data *const this = &total;

this指针一般用于解决重名问题和返回自身的值或者引用。例如:

struct A{
    int a;

    void test(int a){
        this->a = a;
    }
};

test函数的形参a和类成员a成名,根据就近原则,直接使用a,调用的是形参a,那么如何使用被屏蔽的成员a呢,这里就是采用this指针。

2. const成员函数

紧随参数列表之后的const关键字作用为:修改隐式this指针所指向的对象的类型,如下:

/* 假设现在有一个类Sales_data,以及Sales_data类型对象,则在const成员函数中隐式的this指针可以写成如下伪代码形式 */
const Sales_data *const this = &total;

这里加const的含义是,这个函数不能修改本对象,其实就是函数体内不得对类的成员进行修改。const主要起到保护的作用。

注意:非const对象可以调用const成员函数,也可以调用非const成员函数,但是const对象只能调用const成员函数。并且,非const对象优先调用非const成员函数。

最后记住:构造函数不能为const。如果为const,怎么完成初始化工作?!

3. const成员函数和非const成员函数可以构成重载。

到此为止,构成函数重载的要素有:类的名称、函数名、函数形参表以及成员函数的const属性。事实上,函数签名就是由这几个部分构成。

在这里我们解释一个问题: 为什么C语言里面没有函数重载? 因为在编译器编译C程序时会维护一张符号表,C语言在记载函数的时候就是简单的记录函数的名字,所以函数名就是C函数的唯一标识。当我们试图定义两个名字相同的函数时,就发生了重定义。

C++是怎么做的呢? 很显然,对于普通函数,它的符号(唯一标识)是根据函数名和参数列表生成的,对于类的成员函数,还要加上类名和const属性,所以我们进行函数重载的时候,这些函数在符号表中的标识是不相同的。 C++正是通过这种机制实现了函数的重载

注意:C++编译器生成函数符号的时候没有考虑返回值,这也是函数重载和返回值无关的原因。

4. 构造函数之构造函数初始值列表(constructor initialize list)

构造函数有一个特殊的地方,就是它可以包含一个构造函数初始化列表,如下:

Person(int id, const string &name, int age)
         :_id(id), _name(name), _age(age){
}

虽然以下形式,也完全可以达到目的:

Person(int id, const string &name, int age){
        _id = id;
        _name = name;
        _age = age;
}

但两者是不同的。第一种形式带构造函数初始值列表,执行的是真正的初始化工作;而第二种形式,进行的是赋值操作。

注意,即使构造函数没有构造函数初始值列表(更确切的说是构造函数初始值列表为空),那么类中的成员变量将会执行默认初始化。因此在以下情况我们必须使用构造函数默认初始化列表:

a)const内置类型变量以及没有显示定义默认构造函数的const类类型变量(可以参考该博文合成的默认构造函数定义为delete的一种情况

b)引用类型成员

c)没有默认构造函数的类类型变量

其本质是因为,const内置类型变量和引用类型必须初始化;而对于类类型对象,可以通过默认构造函数进行默认初始化(非const类类型对象只要有默认构造函数就可以默认初始化,而const类类型对象必须有显示定义的默认构造函数才可以执行默认初始化)

5. 类成员初始化的顺序是它们在类中声明的顺序,而不是初始化列表中列出的顺序

考虑下面的类:

class X {
    int i;
    int j;
public:
    X(int val) :
    j(val), i(j) {
    }
};

我们的设想是这样的,用val初始化j,用j的值初始化i,然而这里初始化的次序是先i然后j。

记住:类成员初始化的顺序是它们在类中声明的顺序,而不是初始化列表中列出的顺序!

6. 析构函数

与构造函数一样,析构函数也是一种特殊的函数。构造函数在对象被创建时调用,析构函数则是在对象被销毁时被调用。构造函数与构造函数一样,同样没有返回值,并且析构函数没有任何参数。如下:

~Person(){

}

需要引起注意的是:

a)对于类类型对象foo的析构函数只是在它生命期的最后一刻的回调罢了,管不了foo自己所占的内存,就像自己没法给自己收尸一样。

b)对于堆上的类类型对象:free() 干的事情是释放内存。delete 干的事情是调用析构函数,然后释放内存,注意是delete释放的内存空间,而不是析构函数释放的。对于栈上的类类型对象,退出作用域时会自动调用析构函数,然后释放内存。

总结:对于栈上的类类型对象其实和内置类型变量一样,退出作用域后都是由系统自动释放内存的。实际上无论是栈空间,还是堆空间,内置类型对象和类类型对象销毁时的区别,在于类对象会在销毁前调用析构函数。

时间: 2024-12-20 16:38:41

C++回顾(未完待续,长期更新)的相关文章

模板区域[未完待续](会定期的更新哦(有时间就更了))

写这个博客目的就是为了记录下学过的模板方便我这焫鷄复习吧//dalao们绕道 近期学的: (1)来自机房学长jjh大神教的求1~n的所有最小素因数和加上本焫鷄的批注 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath>//求1~n的最小质因数 using namespace std; const int MAXN=1e6+

数据结构与算法之--高级排序:shell排序和快速排序【未完待续】

高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序的是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希尔(shell)排序 希尔排序是基于插入排序的,首先回顾一下插入排序,假设插入是从左向右执行的,待插入元素的左边是有序的,且假如待插入元素比左边的都小,就需要挪动左边的所有元素,如下图所示: ==> 图1和图2:插入右边的temp柱需要outer标记位左边的五个柱子都向右挪动 如图3所示,相比插入排序

听风讲MVC丶 —— 一言不合就撸码 (未完待续&#183;&#183;&#183;&#183;&#183;&#183;)

     希望你看了此小随 可以实现自己的MVC框架     也祝所有的程序员身体健康一切安好                                                                                                                                                ——久伴深海丶默 1.什么是前端控制器(font controller).Java Web中的前端控制器是应用的门面,

Linux 命令个人总结====== 未完待续 个人认为比较重要

Linux 命令个人总结====== 未完待续 man [功能说明]: 查看帮助 [语法格式]: man [123456789] 命令.文件. [选项参数]: 数字"1"表示用户命令,比如"ls" 数字"2"表示系统调用 数字"3"表示C语言库函数 数字"4"表示设备或特殊文件 数字"5"表示文件格式和规则 数字"6"表示游戏及其他 数字"7"表示

关于DOM的一些总结(未完待续......)

DOM 实例1:购物车实例(数量,小计和总计的变化) 这里主要是如何获取页面元素的节点: document.getElementById("...") cocument.querySelector("选择器"); 通过所需的元素节点,得到我们想要的数据做运算. 实例2:伸缩二级菜单 这里主要是逻辑判断,不同的逻辑给不同的className来控制样式. 需求是:一级菜单可以都关闭,但最多只有一个能打开.(思路是,每次都将所有的一级菜单关闭,然后仅打开当前点击的元素,并

某度质量部测试开发面试题1(未完待续)

点击链接加入QQ群 522720170(免费公开课.视频应有尽有):https://jq.qq.com/?_wv=1027&k=5C08ATe 1. 黑盒测试和白盒测试常用的测试方法有哪些?举例说明. 答:白盒测试:逡辑覆盖法,主要包括诧句覆盖,判断覆盖,条件覆盖,判断条件覆盖,组合条件覆盖.路径覆盖. 黑盒测试:等价划分类,边界值分析,错诨推测法等 2. 静态测试和动态测试的概念. 答:静态方法是不运行被测程序本身,仅通过分析和检查源程序的语法.结构.过程.接口等来检查程序的正确性.对需求规格

JavaWeb ajax编程(未完待续)

1.Ajax 1.1Ajax的定义 Ajax:(Asynchronous JavaScript And XML)指异步 JavaScript 及 XML. 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript.XML.HTML.CSS新用法. Ajax:只刷新局部页面的技术 JavaScript:更新局部的网页 XML:一般用于请求数据和响应数据的封装 XMLHttpRequest对象:发送请求到服务器并获得返回结果 CSS:美化页面

whatweb.rb 未完待续

#!/usr/bin/env ruby #表示ruby的执行环境 =begin # ruby中用=begin来表示注释的开始 .$$$ $. .$$$ $. $$$$ $$. .$$$ $$$ .$$$$$$. .$$$$$$$$$$. $$$$ $$. .$$$$$$$. .$$$$$$. $ $$ $$$ $ $$ $$$ $ $$$$$$. $$$$$ $$$$$$ $ $$ $$$ $ $$ $$ $ $$$$$$. $ `$ $$$ $ `$ $$$ $ `$ $$$ $$' $ `$

把握linux内核设计思想系列(未完待续......)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 把握linux内核设计思想(一):系统调用 把握linux内核设计思想(二):硬中断及中断处理 把握linux内核设计思想(三):下半部机制之软中断 把握linux内核设计思想(四):下半部机制之tasklet 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择 把握linux内核设计思想(六):内核时钟中断 把握linux内核设计思想(七):内核定时器和

[译]App Framework 2.1 (1)之 Quickstart (未完待续)

最近有移动App项目,选择了 Hybrid 的框架Cordova  和  App Framework 框架开发. 本来应该从配置循序渐进开始写的,但由于上班时间太忙,这段时间抽不出空来,只能根据心情和兴趣,想到哪写到哪,前面的部分以后慢慢补上. App Framework 前生是是叫 jqMobi 注意大家不要和 jQuery Mobile 混淆了,它们是两个不同的框架,一开始我还真混淆了0.01秒. 这里我先翻译一下Quickstart 部分,一是自己工作上用的上,二是也想顺便练练英文,最关键