C++学习笔记
system()就是调用(DOS)系统命令(和shell命令)。
pause ,即DOS命令集合中的暂停命令;
sprintf
1 | #include <stdio.h> |
- 返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1
- sprintf 返回以format为格式argument为内容组成的结果被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。
引用
声明引用:
1 | int a = 1; |
传引用参数
1 | void func(int& a){} //函数名(xxx)xxx其实是创建形参变量的过程 |
传指针
1 | void func2(int *a){} |
返回引用
返回值不能是局部变量(局部变量在生命期结束后会被销毁)
(c中生命周期结束后,立马销毁,而在python中垃圾回收机制会在判断之后不使用的情况下再销毁)
func2(&b);
增强的for循环:
在vc6.0中 for(int i=4;i>0;i–) i的作用域为 整个外部作用域如
void main()
{
for(int i=4;i>0;i–) //作用域为整个main函数
}
而在vs中 for(int i=4;i>0;i–) i的作用域为 该个for循环内
void main()
{
for(int i=4;i>0;i–) //作用域为该个for循环
}
默认参数 从右往左连续
返回值不是函数重载的条件
malloc和free 不会触发构造函数或是析构函数
new和delete 可以
类
不做特别说明,类的数据成员和成员函数都被认为是private
this指针
- this 是类成员函数的隐含参数,不是类的数据成员
- 静态成员无this指针
常函数
-
常函数不能修改类中的数据成员的值
-
析构函数和构造函数不能是常函数
-
常变量只能调用常函数,不能调用普通函数
-
常对象只能调用常函数,不能调用普通函数
静态成员
- 是类本身的属性,无对象时也可以直接调用Cstu::sta
- 静态成员函数只能调用静态数据成员
类外初始化 不需要static关键字 如: int Cstu::sta = 12;
创建数组
1 | a = new int[2]; |
浅拷贝和深拷贝
- 系统默认的为浅拷贝
- 有指针承运啊时得内存拷贝,所以使用深拷贝,
- 为了避免拷贝构造,运算符重载应该传引用
拷贝构造
何时会调用
1.新建一个对象,并将其初始化为同类现有对象
1 | Cstu a; |
2.当程序生成对象副本时
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- 参数是本类的常引用Cstu(const Cstu&)
- 普通构造函数如果空的话是不执行内容的,拷贝构造空的话是执行内容的
- 默认的复制构造函数,逐个复制非静态成员的值,
## 内联函数inline
- 函数代码少,流程直接,调用频繁,如循环
- 类内定义的都是内联函数(隐式),写inline为显性
- 内联函数的定义一般写在头文件内
- 只在声明位置写inline不管用,定义与声明都要有inline关键字
- 空间换时间,使用频率低时速度快,频率高时,比较占用内存,主要看性价比
- 递归不能是内联函数
## 操作符重载
------
- 为了避免拷贝构造,运算符重载应该传引用或是传地址
- 操作符重载必须有一个类类型的参数
- =、[]、()、->必须是诚邀
- 复合赋值运算符通常是成员
- 改变对象状态的运算符,递增、解引用,通常是成员
### 输出运算符重载:
- 参数1是ostream引用,参数2是对象的常引用
- 必须是类外重载,原因为1
- 输出私有成员时,要用友元
void operator << (ostream& os,const &Csty),os <<st.nAge;
ostream& operator << (ostream& os,const &Csty),os <<st.nAge;
1 |
|
istream& operator >>(istream& ist,CStu& st)
1 |
|
int operator++(Cstu* st){} =>前置++
int operator++(Cstu* st,int n) =>后置++
{
int a =st.nage;
st.nage +=1;
return a;
}
1 |
|
operator int()const{} //无返回值,但有return
1 |
|
template
void func(Y a) cout << a << endl;
1 |
|
temlpate <> void func
1 |
|
▲.类必须先初始化成员变量。
。float c和int d 两个变量的作用域仅限于构造函数内.所以要想在整个类中使用该变量,就得将传入的参数初始化赋值给类中的变量。
若有多个构造函数,会执行初始化列表绑定所在的构造函数(构造函数的重载)
数组的赋值:
- 初始化列表arr()
- 构造函数中for循环赋值
- memset(&arr[0],0,16)
△.析构函数没有重载,且不接受参数。对象声明调用周期结束时自动调用。
▲构造函数和析构函数都必须写在public访问控制符下
malloc和new、free和delete区别
- malloc不会触发构造函数,new可以
- free不会触发析构函数,delete可以
This指针
指针类型为类的类型。
this不是类的成员。
this指针为成员函数的隐含参数,相当于python类中的self…(所以this指针的作用域为类内部)
常函数
1 | class CStu |
◆.析构函数、构造函数不能是常函数
◆.常函数不能修改数据成员(是类的),但可以修改常函数内的变量。
▲常函数的this指针的类型为const CStu*
★常对象(const CStu st)只能调用常函数,不能调用普通函数
静态成员
1 | class CStu |
∷不能在构造函数的初始化列表中初始化,但可以类外初始化
∷类外初始化不用加static,而是int CStu::b = 12;
▲static受访问控制符约束。
调用方法:
1 | 类名作用域:cout<< CStu::b << endl; |
○只有静态常量整型数据才能直接在类中初始化,其他得在初始化列表或者构造函数中赋值(静态数据成员可以类外赋值),普通数据成员不能类外初始化。
●静态成员是跟类一一对应的,跟对象无关。
静态成员函数
他是属于类的属性,不是对象的,即同一个类的所有对象共有一个(可以作为指挥类所有对象的方法)
无this指针
不能调用普通成员,只能调用静态成员
拷贝构造
public:
Cstu(const Cstu &a){} 形式。参数是本类的常引用
何时调用:
1 | 1.新建一个对象,并将其初始化为同类时: |
赋值不会调用:
Cstu s1;
Cstu s2;
s2 = s1;
默认拷贝构造(浅拷贝)
逐个赋值非静态成员,(即默认拷贝构造中是有内容的,默认的构造函数是没有内容的)
内存排布一样,地址不同
深拷贝(涉及类中有指针)
如果是浅拷贝,则两个对象的指针都会指向同一个空间,如果第一个对象被消除后,这个空间就会被delete(free掉),所以第二个对象被删除时再操作(free)这个被释放掉的空间(已经还给系统),就相当于控制野指针,所以会报错。
解决方法1深拷贝:
1 | this->a = new int[2]; |
解决方法2传引用(不经过拷贝构造):
1 | Cstu& fun(CStu& a) |
解决方法3传地址:
1 | Cstu* fun(CStu* a) |
inline内联函数
常规函数的调用过程:调用时,根据函数地址,跳到函数代码空间,执行指令,执行完再跳转到调用的位置。
内联函数:将函数代码直接复制到执行部分,不跳转。
比常规函数稍快
占用更多内存(增加代码长度)
▲声明和定义都要加inline 关键字
▲递归不能是内联函数
△.函数代码少时、调用频繁(for循环里)大多用内联函数(常规函数的话,跳转所耗时间占比就大)
▲.类内定义的函数都是内联函数,但如果定义在类外的话加inline为内联函数,不加就不是内联函数。
△.内联函数通常定义在头文件里。
操作符重载
operator为关键字
“operator+”必须有一个类类型的形参;
继承:
继承控制符:
public 父类:父类为什么访问控制符,子类就继承什么样的。
protected 父类:继承之后,父类的public降级为protected,低级或者同级的访问控制符不变(即protectedh和private)
private 父类:继承之后,父类全变为私有。
多态和虚函数
多态:同样的调用有多种结果
通过虚函数调用子类的成员函数,形式为virtual void Show(){} (函数名与子类相同)
具体执行那个子类的函数由父类所指向的子类所决定. CFather* fa = new CSon1;
C++中声明结构体变量不需要‘struct’,struct默认为public,class 默认为private
c静态变量在预处理时声明。
cpp静态成员在类声明时声明。
STL初始化
-
(1): vector
v; 默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。
-
(2): vector
v2(v); vector
v2= v; 两种方式等价 ,ilist2 初始化为ilist 的拷贝,ilist必须与ilist2 类型相同,也就是同为int的vector类型,ilist2将具有和ilist相同的容量和元素
-
(3): vector
ilist = {1,2,3.0,4,5,6,7}; vector
ilist {1,2,3.0,4,5,6,7};
初始化为列表中元素的拷贝,列表中元素必须与ilist的元素类型相容
-
(4): vector
ilist3(ilist.begin()+2,ilist.end()-1); 初始化为两个迭代器指定范围中元素的拷贝,范围中的元素类型必须与ilist3 的元素类型相容
-
(5): vector
ilist4(7); 默认值初始化,ilist4中将包含7个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0,
-
(6):vector
ilist5(7,3); 指定值初始化,ilist5被初始化为包含7个值为3的int
1 | std::vector<int> idxs中 |
Author: Mrli
Link: https://nymrli.top/2019/07/13/C-学习笔记/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.