学嵌入式Linux发现只有C语言基础开始难学了,必须要上C++,这下来了解C++了
动态内存分配,其实是在堆里申请内存空间
int *p = new int;
int l = new int[20];
C语言用malloc,C++使用new关键字来申请空间
像上面p的语句,申请了一个4字节的空间来存放int类型,而且返回4字节空间的首字节地址,相当于返回一个int *
当你动态内存分配后,这些事都归你自己管,编译器不会处理,所以当你使用完后要撤销这些分配的变量
delete p;
delete[] l;
注意:申请数组后要在撤销语句delete中加[],不然编译没问题,但撤销不完全,会产生垃圾碎片,你和编译器都使用不了
内联函数:
在函数定义前加inline
用于简单的函数语句,一般只有几行指令.原理上就是把调用的函数直接插入程序中;
优点是能提高程序的运行效率,运行更快;
缺点是程序体积更大了,拿空间换时间
函数重载:
名字相同,参数个数或者参数类型不同
使函数的命名变得简单,输入的个数和类型要明确定义,不然会报错二义性,相当于有歧义;
函数的缺省参数,
定义函数时,最右边的连续若干个参数有缺省值,相应位置不写时,参数就是缺省值.
复制构造函数
常用写法 X :: X(const X &)
类中没有复制构造函数则编译器自动生成一个默认的复制构造函数
如果自定义了复制构造函数,则默认的复制构造函数不会生成
如果某个函数有一个参数是类A的对象,呢么调用改函数时,对象调用复制构造函数
一个函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用
注意:对象间赋值并不会调用赋值构造函数
A a1,a2; a1=a2; //这样并不会调用复制构造函数
调用时生成形参会引发复制构造函数调用,开销比较大所以可以考虑使用== CMyclass & ==引用类型作为参数。
如果希望确保实参的值在函数中不应被改变,那么可以加上const关键字
类型转换构造函数
函数中的形参个数只有一个
析构函数
在类名前加
在对象消亡时调用
可以用来删除类中的指针动态内存分配
This指针
早期C++翻译成C语言在C语言的编译器上编译
this指向成员函数所作用的对象
返回时使用this可以返回函数中作用的对象
静态成员函数中不能使用this指针
静态成员变量
在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数
在构造函数中添加静态成员变量增加,而在析构函数中使静态成员变量减少,这是有缺陷的.如果使用了复制构造函数那么静态成员变量不会增加,但消亡时会调用析构函数,所以要增加析构函数,使静态成员变量增加.
int getvalue() const;
int getvalue();
这算重载关系
友元
分为友元函数和友元类两种
友元函数:一个类的友元函数可以访问该类的私有成员
友元类:如果A是B的友元类,那么A的成员函数可以访问B的私有成员.
友元类之间的关系不能传递,不能继承
运算符重载(+,-,*,/)
对已有的运算符赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同的行为
实质是函数重载
运算符重载的实质是函数重载
可以重载为普通函数,也可以重载为成员函数
把含运算符的表达式转换成对运算符函数的调用。
把运算符的操作数转换成运算符函数的参数。
运算符被多次重载时,根据实参的类型决定调用哪个运算符函数。
赋值运算符重载(=)
String S1,S2;
S1=“this”;
S2=“that”;
S1=S2;
这样虽然编译能过,因为S1和S2是相同类型,所以会把S1的指针指向S2的地址,这样S1原来的地址就没人管理,成垃圾了
S1和S2消亡后,S1和S2都会把同一地址delete2次,这样会导致程序奔溃!
如果再执行S1=“other”
会导致S2的内容也变化,不妥
这样先执行删除,再赋值,就不会导致相同类型指向同一地址的问题
再优化一下:
使用String &是考虑到连等于的情况,返回等号左边的引用,方便等号的传递
//有时需要把运算符重载为友元函数
流插入运算符和流提取运算符重载
cout << “hello” << endl;
cout 是ostream类的成员
内部实现:
ostream & ostream::operator<<(int n){
//输出n
return *this;
}
类型转换运算符
方便运算符的执行,像上面的 2 + c 一样
自增自减运算符重载,
前置引用返回自身引用, class & class::operator++(int k)
后置引用返回对象自身;class class::operator++(int k)
最后关于运算符的注意事项: