• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
杏子的成长日记
博客园    首页    新随笔    联系   管理    订阅  订阅
C++

目录
  • 基础问题
    • 68.移动构造函数
    • 78.如何实现只能静态分配和只能动态分配
    • 80.继承机制中对象如何转换?
  • 其他问题
    • 7.C++模板
    • 8.构造函数为什么不能为虚函数?析构函数为什么需要时虚函数?
      • 构造函数:
      • 虚构函数:
    • 10. 构造函数和析构函数可以调用虚函数吗?
    • 11.构造函数和析构函数调用的顺序
    • 12. 虚继承
    • 13.哪些函数不能设为虚函数?

基础问题

68.移动构造函数

我们可能会遇到这样的需求:我们要用B对A进行初始化,而初始化以后,我们就不需要用到B了。那么其实我们就可以直接使用B的内存,而不需要进行额外的拷贝工作。移动拷贝函数它就是去完成这个任务的。移动构造函数和拷贝构造函数的不同之处在于,拷贝构造函数他的参数是一个左值,而移动构造函数的参数是一个右值(将亡值/未命名的值->move)。一般我们在拷贝指针的时候需要进行深拷贝。否则就会出现一个问题:就是拷贝以后的指针指向同一块内存,那么对其中一个指针进行释放以后,另一个指针就会不合法。而移动拷贝构造函数可以使用浅拷贝。解决以上问题的方法就是对原来的指针进行释放。

78.如何实现只能静态分配和只能动态分配

静态分配是指编译器进行分配,其为对象在栈中分配内存;动态分配是指用new进行分配,在堆上进行分配。因为new和delete是运算符,可以进行重载。那么我们将其重载为私有的,就可以实现静态分配,也就是说只能在栈中分配。而我们将构造函数和虚构函数设为protected,并用子类来动态创建

80.继承机制中对象如何转换?

  • 如果是将子类转换成父类,即上行转换,可以直接进行转换,因为可以保证这样转换是安全的
  • 如果是将父类转换成子类,即下行转换,则不一定安全。因为一个父类可能有多个子类。这时就需要用到RTTI技术,也就是动态类型识别技术,用dynamic_cast进行转换。

其他问题

7.C++模板

编译器它并不是把模板函数变成能够处理任意类型的函数,而是需要经过两次编译。首先就是在声明的时候进行编译,其次,在调用的时候也需要对参数进行替换,进行编译。函数模板必须经过实例化以后才能成为真正的函数。

8.构造函数为什么不能为虚函数?析构函数为什么需要时虚函数?

构造函数:

①首先从存储空间的角度来说,我们知道虚函数它的实现是需要虚函数表和虚函数指针。其中虚函数指针是存放在对象的存储空间的。如果我们把构造函数设为虚函数,则就需要相应的存储空间存储这样的一个虚函数指针。但是由于对象还没有创建,也就不存在内存空间,就形成了一个死循环。

②从实现意义来说,我们使用虚函数主要是为了实现多态,也就是父类提供一个接口,子类进行接口继承并进行重写。主要是用于信息不全的情况,那么编译器就会根据具体的类的类型调用具体的函数。但是我们调用构造函数就是创建相应的对象,所以把构造函数设为虚函数也没有什么意义。

虚构函数:

如果我们不把子类的析构函数设置为虚函数,则派生类在析构时,只会调用派生类的析构函数,而不会调用基类的析构函数,这样会造成内存泄漏的问题。而我们把析构函数设为虚函数的时候,派生类虚构时还会调用基类的虚构函数。

10. 构造函数和析构函数可以调用虚函数吗?

一般不会。因为调用的时候都不会进行动态编联。对于构造函数来说,他是首先调用基类的构造函数,再调用子类的构造函数。所以如果在构造函数中调用虚函数,此时派生类中的数据成员可能还没有进行初始化,所以你去访问可能是不安全的;而对于析构函数来说,它是先调用派生类的析构函数,再调用父类的析构函数。所以你在调用基类的析构函数时,子类的数据成员已经被销毁。这时候再调用子类的虚函数就没有意义了。

11.构造函数和析构函数调用的顺序

构造函数:首先调用基类的构造函数,如果有多个基类,按照派生表中出现的顺序进行构造;再调用成员对象的构造函数,最后调用派生类本身的构造函数。

析构函数完全相反。

12. 虚继承

C++支持多继承,一个派生类可以继承多个子类。但是这样会带来一个问题:如果BC都继承A类,而D又同时继承BC 那么A中的成员再BC中都会有,D再去继承的时候,就会出现一个二义性的问题。此时我们可以用虚继承,这样无论基类被继承多少次,都会只保留一个实体。例如BC如果继承A类的时候使用的是虚继承,那么BC中都会有一个bptr,指向虚基类的子对象。如果既存在vptr,又存在bptr,某些编译器会把它进行优化,合并成一个指针。

13.哪些函数不能设为虚函数?

  • 普通函数:虚函数的前提就是它得是成员函数,所以一般的函数是不能被设为虚函数的

  • 构造函数:因为虚函数它的底层原理是有一个虚函数表,然后在派生类当中会有一个vptr,指向虚函数表。而你有这个vptr的前提就是这个对象得有内存空间,但是你既然还没有构造,就不存在内存空间 这样就产生了矛盾。

  • 内联函数:内联函数在编译时对函数体进行替换的操作。而虚函数则是在运行时才能根据类型确定。

  • 静态函数:静态函数不属于某个对象,只属于这个类,它没有this指针。而vptr的访问是需要this指针的。

posted on 2023-06-29 20:56  杏子的成长日记  阅读(10)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3