struct与class的区别:默认的访问权限不同;struct默认权限为公共,class默认权限为私有;
在主函数或者调用函数内部调用一个具有返回值的函数时的注意事项:
在一个类中调用另一个类,并使用函数来传这两个类的参数时需要注意事项:
class A和class B这两个类,在A中调用B,直接使用你定义的类“B”这个名称,声明一个新的变量。
比如"B age;"在主函数中传参时先定义两个变量名。A a;与B b;
1.在使用一个类中包含了另一个类时两个类的定义顺序不对
类A中使用了类B来定义了一个对象,但是此时类B的定义却在类A之后,这就可能产生了“未知重写说明符”的错误。
2.一个封装函数,需要调用两个类时,应该将其放在A类与B类的代码之后
3.
以上为在类A中调用类B的细节展示。
值传递的方式给函数传值:
括号法:
构造函数的调用规则:
提供有参构造,如果我们不自主提供默认构造,编译器也不会提供,但依然提供拷贝构造函数;
如果写了拷贝编译器也不会在提供默认与有参;
总结:没写全提供,有参少默认,拷贝一条龙;
堆区:
new创建返回的是该数据类型的指针。
浅拷贝与深拷贝:
Person p();与Personp1(p)。一次有参构造函数,一次是拷贝构造函数。
此时在析构函数中添加了释放堆区的操作。两次调用析构函数,但只有一个堆区可以被释放。
也就是当第一个函数被调用后在析构函数中释放堆,此时堆为空,再次调用析构函数的释放堆操作就会触发异常;
深拷贝操作就是另外开辟一个堆区,虽然内容相同但地址已经不同了,此时有两个堆区可以被释放就不会触发异常。
所以如果在哪个函数使用析构函数释放堆操作发生异常,只需在这个函数中再申请一个堆。当然内容要相同。假如Person p();与Personp1(p)中,拷贝构造函数触发异常。在拷贝构造函数中添加地址为p.####(这是个例子)的内容:*p.####。用堆重新创造一个该内容的地址。
new int(*p.####)= 用类中设置的指针来接受这个地址。如此就创造了一个内容相同地址不同的堆了。
p走p的析构,p1走p1的析构就不会出现交互重复释放堆的操作了。
A中嵌套B,谁先被调用谁先完成:
静态成员变量:(非静态成员变量属于类的对象上,静态成员变量不属于类对象上)
静态成员函数:(非静态成员函数与静态成员函数都不属于类的对象上)
编译器会给每个空对象分配一个字节空间,是为了区分空对象占内存中的位置,所以每个空对象都具有独一无二的内存地址
每个非静态成员函数只有一份函数实例,上文也提到了静态是大家共享的,非静态一段时间只能有一个对象访问,也就是多个同类型的对象公用这一份代码。
this指针指向被调用的成员函数所属的对象,它是隐含在每一个非静态成员函数中的一种指针,不需要定义直接使用。
this指针的用途:形参与成员变量同名时可以用this指针来区分
在类的非静态成员函数中返回对象本身,可使用return*this。
如果没有使用&,而是返回Person对象的副本,那么链式调用就无法实现,因为每个函数调用都会返回一个新的副本,而不是修改同一个对象的状态
返回引用是为了一直对一个数据进行操作。
还要说一句:不懂得调试只会搞推理的程序员不是好的程序员。
const修饰成员函数:
this指针不能修改指针的指向
成员函数后加上const,使this指针指向的值也不可以修改
普通调用函数可以修改变量的值,所以长对象只能调用常函数;
友元:让一个函数或者类访问另一个类中的私有成员
类外写成员函数:
运算符重载:
不能被重载的运算符只有五个,分别是
1. . (成员访问运算符)
2. * (成员指针访问运算符)
3. :: (域运算符)
4. sizeof (长度运算符)
5. ?: (条件运算符)
成员函数:classA与classB,在classA中写一个Aoperator+(B &变量)的成员函数;
格式 类 operator 符号(类&类内变量);
全局函数:其实就是把成员函数写在类外,多传了一个类内变量而已
格式 类 operator 符号(类&类内变量,类&类内变量)
值得强调的是格式中第一个类看你想要的返回值类型而确定,而括号中的类视实际情况而定,我目前做题目只遇到过相同的类的对象A与B相加和相乘的运算。
重载递增:前置递增返回引用,后置递增返回值。
继承:减少重复代码
语法:class 子类:继承方式 父类
继承方式:
父类中所有非静态成员属性都会被子类继承下去。
父类中的私有属性被编译器隐藏了,访问不到但可被继承。
开发人员命令提示工具查看对象模型:
继承:析构与构造的顺序
继承—同名成员处理
同名成员变量
同名成员函数
无论是同名变量还是同名成员函数,在子类的声明对象中进行调用第一时间返回的是子类的同名变量/函数。
多继承语法:class 子类:继承方式 父类1,继承方式 父类2.......
多态的基本语法:
地址早绑定:编译阶段确定函数地址;解决方法在继承的基态下的同名函数前加个virtual(虚拟)
地址晚绑定:运行阶段去确定函数地址。
访问静态函数:classmate::member或者classmate.member
访问实例函数:classmate.member
对类A的非静态函数取地址
通过创建对象访问函数的方式去访问地址会报错,但通过类下的作用域方式去访问实例函数不会报错,是何缘故我也不清楚。不想打印也可以从监视中看到地址。
多态底层原理:
多态使用条件:父类指针或者引用指向子类对象。
父类申请一个指针指向new开辟的返回的子类对象的地址。
类A申请的指针虽然获取到了类B对象的地址,但是也只能指向类A下的成员函数与变量。
类B申请的指针却可以指向继承的父类(类A)的成员函数与变量以及自身的成员函数与变量。
抽象类:无法实例化对象
抽象类的子类必须要重写父类中的纯虚函数,否则也属于抽象类。
函数重载:1.作用:函数名可以相同,提高复用性
2.条件:同一个作用域下
函数名称相同
函数参数类型不同或者个数不同或者顺序不同
3.注意事项:函数的返回值不可以作为函数重载的条件。