零碎
- 类的关键字:class, struct
- 可以只是声明而不定义(不完全类型),只能用作指针或形参等(依旧不可使用)。这也是为什么可以在类中定义自己的指针。
- const加在形参表之后,且必须同时出现在声明与定义中
Lixiaoqi::show() const {//do sth.};
初始化 / 构造
- 构造函数直接初始化
Lixiaoqi::lixiaoqi() a(1),b(2.0)…{//do sth.};
- 可以指定初始化
className varName = { ... }
要求均为public,还不能有构造函数… - 编写默认构造函数要注意
- 数组
- 动态分配的内存
- vector类型
-
- 如果有可以只接受一个实参的构造函数,那么就定义了一个 这个类 和 这个实参 的隐式类型转换
- 如果不想这样,就在 类内 这个 可接受一个实参 的构造函数声明前写上:explicit
- 单实参构造函数的隐式转换
友元
- 可以是类,可以是函数
- 只要在最前方加上friend即可,位置无所谓
- 友元可以在类内定义,但他算类外定义的
static:🎃所有对象公有
要理解好static成员不被任何类对象所私有
数 据 成 员 = { 还 得 在 类 外 定 义 c o n s t 在 类 内 赋 值 , 非 c o n s t 类 外 赋 值 只 占 用 一 次 内 存 c o n s t 可 以 用 作 默 认 实 参 数据成员=\left\{ \begin{matrix} 还得在类外定义 \\ const在类内赋值,非const类外赋值\\ 只占用一次内存 \\ const 可以用作默认实参 \end{matrix} \right. 数据成员=⎩⎪⎪⎨⎪⎪⎧还得在类外定义const在类内赋值,非const类外赋值只占用一次内存const可以用作默认实参
函 数 成 员 = { 没 有 t h i s 指 针 ( 因 为 不 属 于 任 何 对 象 ) 对 于 类 内 数 据 只 能 操 作 s t a t i c 成 员 可 以 在 类 外 用 c N a m e : : f u n ( . . ) 调 用 不 能 为 c o n s t 和 v i r t u a l 函数成员=\left\{ \begin{matrix} 没有this指针(因为不属于任何对象) \\ 对于类内数据只能操作static成员 \\ 可以在类外用cName::fun(..)调用 \\ 不能为const和virtual \end{matrix} \right. 函数成员=⎩⎪⎪⎨⎪⎪⎧没有this指针(因为不属于任何对象)对于类内数据只能操作static成员可以在类外用cName::fun(..)调用不能为const和virtual
复制控制
1 复制构造函数:接受单个const&类类型的构造函数
//some examples
string s1 = "lixiaoqi";
string s2 = string("lixiaoqi");
- 形参一定要是引用:否则本质传值,形参就需要由实参复制得来,又调用复制构造函数,将无穷递归!
- 默认复制构造函数对数组,vector也复制
- 作容器元素、以引用传递给函数、从函数返回时都要用到! (C++PrimerPlus P195)
2 赋值操作符
- 赋值是对已经存在的进行改动,复制是构造函数
- 要理解赋值的过程是撤销左操作数的内容,再将右操作数赋值给左操作数
- 一定注意自身赋值
3 析构函数
- 三法则:以上控制需要一个,则也需要其他2个
处理指针
- 类中指针管理是门学问,不同对象共享一个指针时容易出乱子
1 智能指针类
- 定义共享的指针类,即智能指针,其中使用计数最为关键
- 对象初始化时,计数记1;删除时,若计数为0,删除指针
- 对象复制,计数加1;赋值,左操作数减1,若为0,删除,再把右赋值给左
2 值型类
- 智能指针使得大家共享指针,但也可以将类看成纯值类型,所有特征只是值,像string一样,复制赋值后各不相干
- 所以初始化、复制只需复制值,指针新开辟一个
- 对于赋值,就不用再开辟指针啦
操作符重载
- 可作为成员函数(this),也可不。
- 重载自增/自减,前缀没有实参,后缀带一个标志性的int(必须是int)
- 重载调用操作符
//example
struct Abstract
{
int operator() (int k) { return k > 0 ? k : -k;}
};
void main()
{
Abstract ab;
cout << ab(-9);
}
- 重载调用操作符后,类对象可以直接做函数用(传递给标准算法)
strcut Tst
{
Tst(int k = 0) : bound(k) {}
bool operator() (int i) { return i < bound;}
private:
int bound;
};
int main()
{
vector<int> ivec;
//ivec.pushback()
sort(ivec.begin(), ivec.end(), Tst(707));
}
- 重载转换操作符
- 格式: operator type() { }
-
- 返回:不指定返回类型,但是要返回 type 类型的值
- 形参: 形参表必须为空!
- 不传递: 只允许转换一次,如
a -> b, b -> c
, 不能在需要c的地方使用a - 建议定义为const函数 //from C++ Primer
函数适配器
- 函数对象from STL
- example
greater_equal<int> (1, 3) // returns 0, for 1<=3 is incorrect
- almost needs 2 opeartors
- binder
- How many: bind1st & bind2nd //bind which operator
- When to use:
- example: stable_sort() needs a function which receive only one argument
- use binder to make STL_operator_reloads a func receiving single arg
-example :bind2nd(greater<int>(), 8); //new_greater : _ > 8
- negator
- How many: not1 & not2 // ~ a func receives 1 or 2 opends
- example :
not1(greater<int>); // <= actually