头文件中需要加入防卫声明
#ifndef XXX
#define XXX
#endif
类的构造函数中,使用列表初始化初始化对象的数据成员
区别:变量的设定,初始化,赋值,使用列表初始化等于在初始化就将值放进去,如果在大括号里面写的话,等于放弃了初始化的阶段,直接在赋值阶段设定对象数据成员的值,后者的效率比前者差
类一般分两类:一类带指针,一类不带指针,不带指针的类大多不用写析构函数
C语言不允许函数重载,C++可以函数重载,构造函数可以有多个,函数重载的实质是编译器会把它们视为名称不同的函数
构造函数放在private的作用:singleton设计模式,将构造函数放在private中,单例模式,不能在类外中创建对象
常量成员函数:在函数声明后面加const,不会改变数据内容的成员函数应该加上const ;如果是一个对象是const对象,如果调用设计数据成员的函数,而这个函数不是const成员函数,此时编译器会报错
const可以将同一个成员函数区分开
当成员函数的const和non-const版本同时存在时,const object只能调用const版本,non-const版本只会调用non-const版本
值传递和引用传递(参数传递):养成使用引用传递的习惯,传引用的速度会更快,const引用可以防止错误修改引用的参数中的内容
返回值和返回引用(返回值传递):返回值的传递也尽量返回引用;
参数的传递和返回值的传递都尽量使用引用传递,原因跟速度和效率有关,传递者无需知道接受者是以引用的的方式接受参数
友元:相同的类的各个对象是互为友元
引用的底层实现可以看作指针
带指针的类,String类就是一个典型的带指针的类,可以根据string的大小来使用指针分配空间
拷贝构造和拷贝赋值,如果自己不定义,编译器将使用默认的拷贝构造和拷贝赋值,在带指针的类中使用默认的拷贝构造和拷贝赋值,将会产生错误,默认的拷贝构造和拷贝赋值在带指针的类当中将会直接复制指针,导致拷贝或者被赋值的那部分直接指向原有指针指向的内容,这并不是真正意义上的拷贝和赋值,
String s3(s1)//拷贝构造
s3=s2//拷贝赋值
//它们在类中的定义
String(const String& str)
String& operator=(const String& str)
编译器默认的拷贝构造和赋值拷贝都是浅拷贝
拷贝赋值函数要检测自我赋值,若出现自我赋值的情况直接返回this
stack:栈对象在作用域结束后被自动清除,它的析构函数会被自动调用
global object:作用域为整个程序
local static object:静态对象,它的生命周期为整个程序,不会在作用域结束后被清理
heap:堆对象的生命在delete之后结束,堆的内存空间由指针来控制,出现内存泄漏的一种情况是,指向一块堆空间的指针的生命周期在作用域之后结束,但是在作用域结束之前没有使用delete回收这块堆空间,因此在作用域之后,这块堆空间就结束了
new:分配内存malloc(内存的大小),类型转换,调用类的构造函数
delete:先调用析构函数,再释放内存free(pointer)
不用太care哪些函数可以写成inline哪些不可以写成inline,将所有写成inline
成员函数只有一份拷贝,non-static members通过this指针来调用不同对象的数据,static data member只有一份拷贝,相同类的所有对象都使用这份拷贝,static member function,它没有this指针,用于对static data member进行操作
类和类之间的关系:复合,继承,委托
复合:has-a,即一个类拥有另外一个类;复合关系下的构造和析构,构造过程是由内而外,析构是由外而内
委托:跟复合有点像,但委托关系中,一个类拥有另外一个类,但这种拥有关系比较虚,拥有的是相应的类的指针,至于什么时候真正拥有这个类并不确定,它们之间的关系通过指针连接,它们的生命周期就不同步,这一点跟复合关系不一样
继承:is-a,public,private,protected继承
继承关系下的构造和析构:构造由内而外,析构由外而内,基类的析构函数是要virtual的
non-virtual函数:不希望子类派生类重新定义它(overwrite)
virtual函数:希望派生类,子类重新定义它,它已有默认定义
pure-virtual函数:希望子类或者派生类一定要重新定义这个函数,对它没有定义
virtual void draw()=0 const;//pure virtual
virtual void error();//impure virtual
int studentID() const;//not virtual
继承加复合关系下的构造和析构:
仿函数类,function-like classes
explict关键字:告诉编译器不要隐式调用构造函数
智能指针里面会包含有普通指针
引用和它代表的对象大小相同,地址也相同;引用大多用在参数传递中,返回值的传递中
继承中,子类继承的是成员函数的调用权
虚指针(vptr):每一个类都带有一根虚指针,虚指针指向一个虚表
虚表(vtbl):虚表中存放着类中虚函数的地址,指示类中的虚函数应该调用哪个版本,若一个子类没有改写父类的虚函数,则它虚表中的这个虚函数这一项指向父类的相应的虚函数;若子类改写了父类当中的虚函数,则指向子类改写之后的虚函数