字面常量不可以有引用,因为这也不需要使用符号来引用了,但是字面常量却可以初始化const引用,这将生成一个只读变量;    
对变量的const修饰的引用是只读属性的;
也就是说,const修饰的引用,不管是变量初始化还是字面常量初始化,总是对应一个只读变量。

#

函数能够重载和返回值无关,所以两个函数若是只有返回值不同,这是无法重载的。

  

#

直接调用构造函数将产生一个临时对象,其生命周期只在一条语句时间,作用域仅在一条语句内。

现代C++编译器会尽量(是看情况去尽量,有些情况不一定确保)减少临时对象的产生,例如用一个临时对象来初始化一个新对象的场景。
减少临时对象产生,也就能减少构造函数调用的次数,加大程序执行的效率。

 

# 

类中的const成员一定不是常量。

const成员函数注意事项:const成员函数在类中的声明处,和const成员函数的定义处,的后面,
加上const修饰。 const对象只能调用const成员函数,const成员函数只能调用const成员函数,
const成员函数内不可以直接改写成员变量的值。
注意理解上面的话,也就是说,
如果const对象的某个const成员函数内嵌套调用多个子成员函数,
那这些子成员函数都必须是const修饰。 const对象,可以定义非const与const成员函数,但是只能调用const成员函数。 const对象的成员变量是只读变量,编译时作是否在赋值符号左边的检查。
const对象的成员变量可以在构造函数(例如普通有参或无参构造函数和拷贝构造函数)中被初始化。要注意初始化和赋值的不同。
言不及意,具体请看下面图片代码所要表达之内容。

#

运算符重载规则和函数重载一样:根据函数参数决定能否构成重载关系,与返回值无关。

#

int a = 1; int b = ++a; 这样应该是a是2 b是2 。int a = 1; int b = a++; 这样应该是a是2 b是1 。

#

引用很容易与指针混淆,它们之间有三个主要的不同:

1 不存在空引用。引用必须连接到一块合法的内存。
2 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
3 引用必须在创建时被初始化。指针可以在任何时间被初始化。

#

静态成员变量在类外分配空间,是在全局数据区分配空间,也就是说其存储区和静态局部变量,全局变量是一样的。
同时需要注意,静态成员变量也必须在类的外部进行定义。
可以通过类名访问静态公有成员变量。静态成员变量为整个类所整个类所有。
和成员函数跟类似啊,那么,可以通过类名访问公有的成员函数吗?
==》 当然不可以,见下图
自己也假设个场景思考下该问题:
通过类名访问成员函数,不带this指针。
举个例子:假设通过类名了调用了一个该成员函数,且该成员函数内访问了某成员变量,
因此种方式调用成员函数不带有this指针,故无法判定该去获取哪个对象的成员变量)。

可以通过类名访问公有静态成员函数。但
是静态成员函数不可以直接访问非静态的成员变量,因为不含this指针信息。 静态成员函数不需要实例化就可以被调用,不可以调用非静态成员(包括静态成员变量和成员函数)
反正一个意思: 不带this指针的,和带this指针的,不能沾上边就行了。

因为非静态成员函数可以访问非静态的成员变量(每个对象都有自己各自的非静态成员变量),
这即表明非静态成员函数隐含了this指针信息, 而静态成员函数不含有this指针信息,这是固定属性,
也无法通过访问非静态成员来改变其属性,使其包含this指针信息。
关于静态成员函数与非静态成员函数。
我有点理解了,编译器就是搞了这两套东西。
相辅相成,为方便用户使用而做的。
条条大路通罗马,多搞他一条路,用起来时或许能方便些。 一套带this,一套不带this。前者是私家车,后者是公交车。
私家车上会有吃私房菜(调用非静态成员变量)的需要,所以要携带this指针信息。 公交车上就吃统一的盒饭:只能调用静态成员变量或其他静态成员函数
(如果调用了其他公交车,也肯是只能吃统一的盒饭)

对静态成员函数的一点备注,结合单例模式时的使用:

plus say: 上述截图扯到了单例模式,图中代码所展示的单例模式的使用方法也可以称之为二阶构造法。

二阶构造,应该说是个人的一种编程风格吧。第一阶段不涉及系统资源的申请,
那也可以合并入第二阶段啊。
本质还是要检查系统资源申请是否有效(大多是根据返回值检查,如new malloc fopen 等),
如果申请失败则执行析构函数,释放目前已经申请到的资源,
例如之前申请资源时,执行fopen文件a成功了,但是fopen文件b失败了,
所以在此处析构内应该执行fclose文件a)。
看来还要维护一个已打开资源的数组或链表。
二阶构造方法可以结合保存已打开资源的数组或链表,使得代码更加清晰,
一眼就能判断出析构的时机,以及在析构函数内应该释放哪些资源。

  

#

重载赋值操作符相对其他运算符有些特殊,只能作为成员函数来重载。
运算符重载规则和函数重载一样:根据函数参数决定能否构成重载关系,与返回值无关。
C++中的重载能够扩展操作符的功能。操作符的重载以函数的方式进行,操作符重载的本质就是用特殊形式的函数扩展操作符的功能。
我们使用operator关键字来标识该特殊函数。

  

#

引用是指针常量,指针常量是指如 int* const p = 。。。;这样的指针,也就是说*p是可以改变的。

int *p = new int(5);
int &a =*p;
此时p指向一个无名的变量,该变量由*p表示,所以int &a =*p;
这个问题可以查找c++标准关于operator*的返回值类型的描述。 是左值,才可以初始化非const引用。
来自网友菜鸟大神的解释: 用专业术语说,表达式*p的值是个int类型的左值,所以可以初始化非const引用。而 int a,b;
表达式a+b的值是int类型的右值,所以不能初始化非const引用。 关于左值和右值,可以参考c++标准operator*的返回值类型的描述。
我的实测如下图:

#

类的成员函数可以访问该类的所有成员变量,无论是否public修饰。类的成员函数只有一套,是共用的。

#

1. 只要一个类不含有虚函数, 那么实例化对象时,可以不必实现该类内部的成员函数,只声明即可。

2. 只要一个类拥有虚函数,当定义实例化该类对象时,就必须实现其全部的虚函数定义,否则编译报错。
( 当一个子类继承于父类时,子类内的重写虚函数(与父类内的某个虚函数:同函数名、返回值、函数参数)也是虚函数:
在实例化该子类对象时,也必须实现子类内部存在的全部虚函数定义,否则编译报错。)

  

#

要严格区分,只有在构造的时候,()和=可以无差别使用,都表示初始化。
但是在进行纯粹赋值的时候,例如非构造函数的其他成员函数在调用时被赋值,obj.normal_func() = 99;
此时只能用=来表示该赋值,而不能使用() .
要注意判别当前过程是构造还是赋值。

#

函数调用操作符是可重载的,且只能重载为类的成员函数。
函数调用操作符可以有多个不同的重载函数。
重载函数调用操作符的意义在于取代函数指针
(我的理解:
以前是传递函数指针,现在只需要传递对象引用即可,通过引用获取函数对象)。
有了函数对象以后,当我们看到MyClass obj; obj(99); 这样的语句们时,千万不要觉得诧异,
为啥已经构造过了,后面又调用一次obj(99) ?
那么此时单看仅有的这两条语句,应该存在两种可能性:
1. obj(99) 等价于obj=99, 这是在赋值
2.obj(99) 这是在调用obj对象的仅带一个参数的函数调用操作符的重载函数,99是传入的参数。

#

只能通过成员函数来重载数组操作符,该重载函数能且仅能使用一个参数。
数组操作符重载能够使对象模拟数组的行为。

#

如果一个类看似是空的,
实则包含了编译器默认提供的无参构造函数、拷贝构造函数、重载赋值操作符函数、析构函数。
当用户提供了自定义构造函数(自定义拷贝构造函数也算),编译器不再提供默认的无参构造函数。

#

在进行深拷贝的时候必须重载赋值操作符;
赋值操作符重载函数和拷贝构造函数具有同等的重要意义;
string类,在一块数据空间上保存字符数据,借助一个成员变量保存当前字符串长度信息;C++开发时应该避免C中的惯用思想,
例如指针使用、
直接通过char* p指向的字符串给string类对象赋值
(这种操作是不会改变string类对象内部表示字符串长度信息的成员变量的!)等。

#

智能指针一句话概念释义: 智能指针类对象在其生命周期结束后会自动释放所指向且涉及到的相关所有堆内存。
智能指针三板斧:
1. 在仅带一个参数的构造函数内对智能指针类内部的它类指针赋值,使其指向外部的它类对象。
2. 使用成员函数的方式重载指针访问->操作符(返回值为智能指针内部的它类指针) 和
*操作符(返回值为智能指针内部的它类指针指向的它类对象)。
3.在析构函数内delete它类指针(这就可以触发它类对象的析构函数被执行)。
按照上述已有的分析,我们现在或许可以写出令一个智能指针a指向一个智能指针b,再令b指向c…指来指去很多次,最后才指向实际的用户对象,这样的代码,
稍加思考,这必将成为日后bug的一个来源。
良好的编程经验要求: 一块堆内存最多只能由一个指针来标识。
这是非常重要的一点,
接下来我们继续实现的拷贝构造函数和赋值操作符重载函数就受此影响:
我们要完成指针指向内存所有权的转移(复制后,再delete原有的指针),而不是单纯复制。

#

#

#

#

#

#

#

#-----------------------------------------------------------

多种初始化方式: int a(5) ;、  int a=5; 、   int a{5}; 、int a[]{1,2,3};、int a[] ={1,2,3};
可以看出使用大括号{}符号初始化数组元素,会依次调用构造函数。
使用大括号{}符号初始化的优势是可以避免隐式转换
(待增补实验:用类的对象,子类对象初始化父类对象,来进一步验证该结论)。 ?
避免隐式转换的好处在于有时能通过编译器报错来使程序员能更全面地掌控程序。

  

#

#-----------------------------------------------------------

序列式容器,其存储的都是 C++ 基本数据类型(诸如 int、double、float、string 等)或使用结构体自定义类型的元素。

关联式容器则大不一样,此类容器在存储元素值的同时,还会为各元素额外再配备一个值(又称为“键”,其本质也是一个 C++ 基础数据类型或自定义类型的元素),
它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素,而无需再通过遍历整个容器的方式。
也就是说,使用关联式容器存储的元素,都是一个一个的“键值对”( <key,value> ),这是和序列式容器最大的不同。
除此之外,序列式容器中存储的元素默认都是未经过排序的,而使用关联式容器存储的元素,默认会根据各元素的键值的大小做升序排序。 C++ STL 标准库提供了 4 种关联式容器,分别为 map、set、multimap、multiset。

.

最新文章

  1. iOS开发小技巧 - label中的文字添加点击事件
  2. MyBatis入门学习教程-Mybatis3.x与Spring4.x整合
  3. Linux学习笔记(二)
  4. [转]mysql 乱码问题解决终结
  5. 【python】判断字符串日期是否有效
  6. java内存分配详细论
  7. CocoaPods requires your terminal to be using UTF-8 encoding
  8. [Practical Git] Switching between current branch and last checkout branch
  9. cStringIO模块例子
  10. jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限
  11. UVa10723 - Cyborg Genes
  12. Hash算法的讲解
  13. 解决Unable to load native-hadoop library for your platform
  14. 第21月第9日 windows下使用vim+ctags+taglist
  15. 20165221 JAVA第五周学习心得
  16. asp.net 基础内容
  17. centos7----pstree
  18. apache+php windows下配置
  19. PHP 5.3版本上MS SQL Server的连接配置
  20. maven项目中的报错问题——Dynamic Web Module 3.0 requires Java 1.6 or newer.

热门文章

  1. 常用Oracle SQL集锦
  2. vmware虚拟机Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)详解
  3. Photon PUN 二 大厅 &amp; 房间
  4. Lua C API 书籍
  5. spring集成shiro,事务失效问题 not eligible for auto-proxying
  6. Fibonacci and Counting(水题)
  7. Java内存模型分析
  8. 【Spring】IOC容器注解汇总,你想要的都在这儿了!!
  9. Class 文件结构及深入字节码指令
  10. LayUi超级好用的前端工具