Table of Contents generated with DocToc
- 数组定义和值初始化的语法形式混淆
- 捉摸不定的评估求值顺序
- 运算符的优先级问题
- 取大优先解析原则带来的问题
- 声明修饰符次序的小聪明
- “函数还是对象”的多义性
- 效果漂移的类型量化饰词
- 自反初始化
- 静态连接类型和外部连接类型
- 运算符函数名字查找的反常行为
- 晦涩难懂的operator->
- 导航
int *ip = new int(12);
ip指向的是单个的一个整数。
int *ip = new int[12];
正确的内存申请方法。
最好的内存申请形式就是根本不去申请,直接用标准库的组件:Vector或者其他。
函数参数的求值没有固定的顺序,必须手动消除这样的副作用。
子表达式的求值次序也不一样,运算符的优先级和结合性对求值次序没有影响。
new会比类型的构造函数先调用,先为对象拿到存储,再在这个存储上初始化它。
逗号,三目运算符有求值顺序的。
逻辑运算符&&和||有短路特性,也算是有顺序么?YEP。
C++中,没有非结合的运算符。
a>b>c
,合法,但可能词不达意。
词法分析引入取大优先解析原则:尽可能取长的字符序列作为词法单位。
a+++++b是非法的,它被解析为a++ ++ +b。
list<vector> lovos也是错的,list<vector 空格> lovos。
先写连接修饰词,再写量化修饰词,再写类型。
extern const int size = 1024
。
指向常量的指针有两种声明形式:
const int *pc;
int const *pc;
对象的默认初始化语句不应该写成一个空的初始化参数列表的形式,因为它会被解释成一个函数声明。如String x()。
该多义性在new表达式中并不发作:String *p = new String(),可以。
内建数组不可能有const或volatile,所以修饰它的类型量化饰词(const或volatile)的效果实际上会漂移,转而应用到其持有物的某个适当位置,
量化饰词的实际效果会转移到数组的元素上去了。
int var = 1;
{
double var = var; //编译通过,但行为未定义,右边用到的var正是刚刚声明的
}
const int var = 1;
{
enum{var = var};
}
这是可以的,枚举的声明位置,与变量不同,是在它的初始化对象(枚举的定义)之后的。后面一个var是外层作用域中的常量。
根本没有本条款名称所说的这种东西。
连接类型饰词总是绑定到对象或函数,而不是类型。
static class R
{} r; //静态的
R r2;//非静态的
匿名名字空间
namespace{
R r2;
R r;
}
这样,r和r2就有了外部连接类型,能有比用static修饰用在更多的地方,而且就像静态对象一样,它们在当前编译单元以外的地方不可访问。
当我们记不住中序记法时,函数调用更清晰。
a = b;
a.operator = (b)
中序和函数调用的名字查找顺序不一样。
内建的operator->是二元的,重载版本的operator->是一元的。对于重载的operator->的调用,必须返回一个可以用(内建的)operator->访问其成员的。
operator->的调用序列的触发总是由包含operator->之定义的对象静态决定的,而且该调用顺序总是终结于返回指向class对象的内建指针的调用。
上一章:1. 基础问题.md
下一章:3. 预处理器问题