默认构造函数
- 如果我们没有显式的定义构造函数,那么编译器将会创建一个默认的构造函数;一旦我们定义了任何构造函数,那么除非我们再定义一个默认构造函数,否则该类讲没有默认构造函数;
- 默认构造函数与自定义的构造函数似乎没有什么不同,但是实际上还是存在区别,例如类中包含有数组和指针,默认构造函数将会导致野指针等类似问题,此时需要自定义默认构造函数再内部控制对象初始化;这种情况同样可以扩大到类中,如果该类包含其它类,但是其他类没有默认构造函数,为了完成其他类的初始化,那么为该类自定义默认构造函数同样必不可少;
析构函数中的delete[ ]
- C++中的new相当于C语言中的malloc,如果我们分配一个对象那么就用new char[], 如果要分配一组对象那么就要用new char[n];但是需要注意的是,前者可以用delete m_data, 也可以用delete [ ]释放空间,但是后者只能用delete [ ]释放空间,如果用delete释放new [ ]分配的空间,那么将会只释放第一个,从而导致内存泄漏;基于上述原因,所以我们一律使用delete[ ]在析构函数中释放分配的空间;
赋值函数
- 赋值函数返回引用;当我们给一个值赋值时,只有返回其本身引用才有意义,否则如果返回一个新的变量,那么将会毫无意义;
- 自我判断;赋值时无法避免把自己赋给自己,所以必须在函数内部加以判断;
- 释放原有空间,分配新的空间 ;为什么不在原有空间上赋值,而必须销毁之前的,再创建一个新的呢?首先无法确保原有空间是否足够,其次就算足够那么我们也会浪费空间;
拷贝构造函数
- 拷贝构造函数分浅拷贝与深拷贝:浅拷贝仅复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,而深拷贝会另外创造一个一模一样的对象,新对象与原对象不共享内存,修改新对象不会修改原对象;如果一个类里有指针,那么则必须对该指针进行深拷贝,反之,浅拷贝即可满足条件;
运算符重载与友元函数
- 为什么在可以使用类成员函数进行运算符重载的情况下,还要使用友元函数进行运算符重载,这是因为可能存在下列情况:A = B*2.75; 那么这个对应的是A = B.operaotr(2.75); 那么反过来呢?A=2.75*B;由于2.75并非对象,那么这种情况就无法成立,在此基础上,所以需要使用友元函数进行运算符重载;针对A=2.75*B就可以和class1 operator\(double m,const class1 &t)进行匹配;对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。
- 友元函数需要注意他的作用域;如果一个友元函数在类中声明,在类外定义,那么这种情况是没有问题的;但是如果一个友元函数在类中定义呢?那么此时友元函数变成了一个内联函数,但是需要注意的是,由于此时其在外部未被声明,那么无论在类内部还是外部都不能被调用;
1 | struct X{ |
友元类
- 友元类可以类比友元函数,一个类的友元类可以访问此类中包括非公有成员在内的所有成员;
1 | class Screen{ |