-
只有成员函数,而且成员函数都是纯虚函数的类叫做接口类,接口类代表的是一种子类所具有性质,
查看全部 -
异常捕获与处理
查看全部 -
typeid注意事项:
1、type_id返回一个type_info对象的引用
2、如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数
3、只能获取对象的实际类型
查看全部 -
dynamic_cast注意事项
只能用于指针和引用的转换
要转换的类型必须有虚函数
转换成功返回子类地址,失败返回NULL
查看全部 -
1、接口类的概念
仅含有纯虚函数的类称为接口类
接口类通常用来表达一种能力或协议(父类一般更适合为接口类)
查看全部 -
拥有纯虚函数的类叫做抽象类,抽象类不能实例化,如果抽象类的子类把父类中所有的纯虚函数都实现的话,此时的子类就不是抽象类了
查看全部 -
父类指针指向子类对象,通过父类指针只能寻址到从父类继承到的成员函数与数据成员,子类扩展的将会被截断。但是,如果将父类中同名函数设置为虚函数,创建子类对象时将会创建子类自有的虚函数表,虚函数表指向的成员函数将覆盖父类中的同名函数
查看全部 -
1、在类实例化的对象当中,他的数据成员所占据的内存大小(数据成员,不包括成员函数),即为对象的大小
2、对象的地址,通过一个类实例化了一个对象,那么这个对象在内存当中会占有一定的内存单元,这个内存单元的第一个内存单元的地址也就是这个对象的地址
3、对象成员的地址,当用一个了类去实例化一个对象之后,这个对象可能有一个或者多个数据成员,每一个数据成员所占据的地址,那么就是这个对象成员的地址
对象的每一个数据成员因为数据类型不同,所以占据的内存大小也有不同,所以地址也是不同的
4、虚函数表指针指的是在具有虚函数的情况下,实例化一个对象的时候,这个对象的第一块内存当中所存储的是一个指针,那么这个指着就是虚函数表指针,该指针指向虚函数表,因为它也是一个指针,所以它占据内存大小也应该是4.
5、int *p=(int *)&shape; 定义p指向shape这个对象。(将shape类型的地址转化为int类型地址)
查看全部 -
1、有虚函数的父类指针生成时会同时生成一个指向虚函数表的虚函数表指针,而虚函数表中有各个虚函数的入口,父类指针就可以通过虚函数表指针找到虚函数表,再通过虚函数表找到要执行的虚函数
2、而实例化子类时,子类也会通过继承父类的虚函数表为自己的虚函数表,子类与父类的虚函数指针不相同,但是虚函数的入口地址一样,此时就能调用父类的虚函数,如果子类定义了与自己父类同名的虚函数,此时这个虚函数的入口地址就与父类的不同
3、如果在子类和父类出现同名函数,如果子类没有定义为虚函数时,这个函数在虚函数表中的入口地址和父类虚函数表中的地址是相同的,而定义了虚函数,子类虚函数表就会出现一个函数地址覆盖掉父类的地址,此时访问的就是子类中的函数
4、如果在父类中定义了虚析构函数,在虚函数表中就会有一个父类的析构函数的函数指针指向父类析构函数入口,定义子类时有虚析构函数,此时用父类指针指向子类对象,就可以通过子类的虚函数指针找到虚函数表,此时调用子类的析构函数,然后再执行父类的析构函数,所以虚析构函数可以避免多态中的内存泄漏,
查看全部 -
虚函数的实现原理
实例化对象shape时,该对象有虚函数,除过生成成员变量时同时会生成一个指向虚函数表的虚函数表指针,而虚函数表中有各个虚函数的入口,父类指针就可以通过虚函数表指针找到虚函数表,再通过虚函数表找到虚函数
查看全部 -
虚析构函数主要解决多态中的内存泄漏问题
查看全部 -
virtual的使用限制
1、普通函数不能是虚函数,也就是virtual只能修饰类的成员函数,不能修饰全局函数
2、静态成员函数不能是虚函数,因为静态成员函数是整个类的,而不是和某个对象共同存在的
3、内联函数不能是虚函数,如果修饰了内联函数,那么会忽略掉inline关键字
4、构造函数不能是虚函数
查看全部 -
动态多态中存在内存泄漏问题。
借用父类指针去销毁子类对象时,只会执行父类的析构函数,此时子类的析构函数执行不了,如果子类构造函数有申请动态内存,子类定义的数据成员无法释放,就产生了内存泄漏,解决的方法就是定义子类的析构函数为virtual析构函数(虚析构函数)
查看全部 -
拥有纯虚函数的类叫做抽象类,抽象类不能实例化,如果抽象类的子类把父类中所有的纯虚函数都实现的话,此时的子类就不是抽象类了
查看全部 -
如果在父类中定义了虚析构函数,在虚函数表中就会有一个父类的析构函数的函数指针指向父类析构函数入口,定义子类时有虚析构函数,此时用父类指针指向子类对象,就可以通过子类的虚函数指针找到虚函数表,此时调用子类的析构函数,所以虚析构函数可以避免内存泄漏
查看全部
举报