C++98/03拾遗
const
关键字
常量修饰符
const
变量不再允许延迟赋值,必须于声明时赋值。
1 | const int MAX_VALUE; // ERROR! |
而下例是允许的,因为其是指向常整型的指针变量。
1 | const int* pt; |
而指向整型变量的常指针的声明如下。
1 | int *const pt; |
对于迭代器而言则如下。
const iterator
允许改变迭代器所指之物的值,但不允许指向其他东西;1
++it; // ERROR!
const_iterator
不允许改变迭代器所指之物的值,但允许指向其他东西。1
*cIt = 0; // ERROR!
const
成员函数
Physical Constness
不得更改对象之任何非static
成员变量,又称Bitwise Constness。
Physical const is stronger than logical const; if an operation is physically const it is also logically const.
Logical Constness
允许在客户端侦测不出得情况下修改对象。
mutable
是与const
成员函数相关的摆动场,用于声明允许const
成员函数更改的成员变量。
1 | private: |
当
const
成员函数和非const
成员函数有着实质等价的实现时,令非const
版本调用const
版本以避免代码重复。
数组的引用
C++中没有「引用的数组」(array of reference),形如int&a[N]
将非法。
ERROR: declaration of 'a' as array of references.
但有“数组的引用”,形如int(&a)[N]
,其作用之一是防止数组退化为指针。
下例的
&
是必须的,否则会产生编译期错误,原因是纯粹的auto推断使引用信息丢失。
1 | int a[2][3] = { 0, 1, 2, 3, 4, 5 }; |
「数组的引用」还能与模板一同发挥作用。 1
2
3
4template<typename T, int N>
void sort(T(&a)[N]) { ... }
...
sort(a);
复制和赋值
1 | Box b1; |
指向成员函数的指针
通过&
创建,访问时使用.*
或->*
。
下例中
&A::func
的&
有时能省略。而在Visual Studio 2015/2017中,省略&
将会报错。
A::func
:非标准语法。请使用&
来创建指向成员的指针。
1 | A a; |
共有友元函数
1 | class B; // 必须前置声明 |
特殊的运算符重载
仿函数(Functor; operator()
)
又称伪函数。使用仿函数的示例见此。
operator new
和new
1 | class A { |
输出如下。
1 | operator new() |
总结如下。
new
=operator new
+ 构造;delete
= 析构 +operator delete
两种类型的operator[]
1 | // const对象 |
避免代码重复的操作如下。
1 | // 非const对象 |
自增/自减运算符
1 | A & A::operator++() { // 前缀 |
流运算符
返回引用是因为
istream
和ostream
不允许拷贝。
1 | friend istream & operator>>(istream & in, A & a); |
其他
不允许重载的运算符有成员访问运算符.
、成员指针访问运算符.*
、域运算符::
、三元条件运算符?:
和sizeof
运算符。
重载箭头运算符operator->
的方式如下。
1 | A* operator->() { return this; } |
重载&&
和||
运算符,并不能复现短路求值的规则。
定位new(Placement new)
需包含如下头文件。
1 |
在已分配的内存空间上实施构造,释放时不使用delete
。
1 | class A { |
模板的实例化和特化
(显式/强制)实例化;
1
template class A<TYPE>;
(显式)特化/具体化。
1
template<> class A<TYPE> { ... };
谓词(Predicate)
谓词共计三类如下。
- 函数/函数指针谓词;
- lambda表达式谓词;
- 仿函数谓词。
带捕获列表的lambda不可以隐式转换为函数指针。
1 | void (*ptr)(int) = [&](int) { }; // ERROR! |
统一三类谓词的函数参数传递方式如下。
标准库实现;
1
2template<typename Pred>
void fun(Pred p) { ... }使用
function
。需包含如下头文件。
1
1
void fun(function<bool(...)> p) { ... }
使用function
获取类成员函数如下例。
下例的
const
仅当f
为const
函数时需要,而f
为类静态成员函数时,则不需要cosnt A &
类型的第一个参数。
1 | function<void(const A &, ...)> func = &A::f; |
数字—字符串的转换
需包含如下头文件。
1 |
数字转字符串如下例。
若重复利用同一个
stringstream
对象,需要调用clear()
,否则将引发错误。
1 | stringstream ss; |
stringstream
也可实现字符串到数字的转换。