【C++基础】析构函数和构造函数面试知识点总结

0

🌈欢迎来到C++基础专栏
🙋🏾‍♀️作者介绍:前PLA队员 目前是一名普通本科大三的软件工程专业学生
🌏IP坐标:湖北武汉
🍉 目前技术栈:C/C++、Linux系统编程、计算机网络、数据结构、Mysql、Python(目前在学)
🍇 博客介绍:通过分享学习过程,加深知识点的掌握,也希望通过平台能认识更多同僚,如果觉得文章有帮助,请您动动发财手点点赞,本人水平有限,有不足之处欢迎大家扶正~
🍓 最后送大家一句话共勉:知不足而奋进,望远山而前行。
————————————————

1.构造函数

1.1说说构造函数有几种,分别有什么用

  • 默认构造函数
    给函数的参数提供默认初始化的值

  • 初始化构造函数
    给函数参数初始化 有初始化函数就不会使用默认构造函数

class Student
{
public:
//默认构造函数
Student()
{
 num=1001;
   age=18; 
}
//初始化构造函数
Student(int n,int a):num(n),age(a){}
private:
int num;
int age;
};
int main()
{
//用默认构造函数初始化对象S1
Student s1;
//用初始化构造函数初始化对象S2
Student s2(1002,18);
return 0;
}
  • 拷贝构造函数
    复制一个类
class Test
{
  int i;
 
  int *p;
public:
  Test(int ai,int value)
 {
    i = ai;
    p = new int(value);
 }
  ~Test()
 {
    delete p;
 }
  Test(const Test& t)
 {
    this->i = t.i;
    this->p = new int(*t.p);
 }
};
//复制构造函数用于复制本类的对象
int main(int argc, char* argv[])
{
  Test t1(1,2);
  Test t2(t1);//将对象t1复制给t2。注意复制和赋值的概念不同
  return 0;
}
  • 移动构造函数
    移动构造函数是C++11引入的一个特性,用于提高对象在内存中的移动效率,避免了不必要的深拷贝操作。移动构造函数通常用于实现右值引用(Rvalue Reference)的语义,其语法形式如下:
class MyClass {
public:
    // 移动构造函数
    MyClass(MyClass&& other) {
        // 执行移动操作,将资源从 other 转移到当前对象
        // 通常是通过将指针所有权转移,而不是进行深拷贝
    }

    // 其他成员函数和构造函数...
};

移动构造函数的关键是将资源(例如堆上分配的内存、文件句柄等)从一个对象“移动”到另一个对象,而不是进行拷贝。这可以大大提高性能,特别是在涉及大量数据或者资源时。

移动构造函数通常与右值引用一起使用,右值引用允许我们引用临时对象或者表达式的结果,从而在编译器级别上表示“这个对象即将被移动”。

MyClass createObject();  // 返回一个临时对象

MyClass obj = createObject();  // 调用移动构造函数,而不是拷贝构造函数

在上述代码中,createObject() 返回一个临时对象,然后移动构造函数被调用来将这个临时对象的资源转移到 obj,而不是执行传统的拷贝操作。

移动构造函数的使用通常需要类具有管理资源的能力,例如使用动态分配的内存、文件句柄等。 C++ 标准库中的很多类都已经实现了移动构造函数,以提高性能。

2.简述下向上转型和向下转型

  1. 子类转换为父类:向上转型,使用dynamic_cast<type_id>(expression),这种转换相对来说比较
    安全不会有数据的丢失;
  2. 父类转换为子类:向下转型,可以使用强制转换,这种转换时不安全的,会导致数据的丢失,原因
    是父类的指针或者引用的内存中可能不包含子类的成员的内存。

3.简述下深拷贝和浅拷贝,如何实现深拷贝

浅拷贝:又称值拷贝,将源对象的值拷贝到目标对象中去,本质上来说源对象和目标对象共用一份
实体,只是所引用的变量名不同,地址其实还是相同的。举个简单的例子,你的小名叫西西,大名
叫冬冬,当别人叫你西西或者冬冬的时候你都会答应,这两个名字虽然不相同,但是都指的是你。
2. 深拷贝,拷贝的时候先开辟出和源对象大小一样的空间,然后将源对象里的内容拷贝到目标对象中
去,这样两个指针就指向了不同的内存位置。并且里面的内容是一样的,这样不但达到了我们想要
的目的,还不会出现问题,两个指针先后去调用析构函数,分别释放自己所指向的位置。即为每次
增加一个指针,便申请一块新的内存,并让这个指针指向新的内存,深拷贝情况下,不会出现重复
释放同一块内存的错误。
3. 深拷贝的实现:深拷贝的拷贝构造函数和赋值运算符的重载传统实现:

STRING( const STRING& s )
{
  //_str = s._str;
  _str = new char[strlen(s._str) + 1];
  strcpy_s( _str, strlen(s._str) + 1, s._str );
}
STRING& operator=(const STRING& s)
{
  if (this != &s)
 {
    //this->_str = s._str;
    delete[] _str;
    this->_str = new char[strlen(s._str) + 1];
    strcpy_s(this->_str, strlen(s._str) + 1, s._str);
 }
  return *this;
}

这里的拷贝构造函数我们很容易理解,先开辟出和源对象一样大的内存区域,然后将需要拷贝的数
据复制到目标拷贝对象 , 那么这里的赋值运算符的重载是怎么样做的呢?
02
这种方法解决了我们的指针悬挂问题,通过不断的开空间让不同的指针指向不同的内存,以防止同一块内存被释放两次的问题。

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值