【复试笔记】C++

张开发
2026/6/19 16:46:29 15 分钟阅读
【复试笔记】C++
Student s2 = { 1002, “s2”, 21, “s222” };这种属于拷贝构造吗答:这属于聚合初始化,而不是拷贝构造,等价于Student s2{ 1002, “s2”, 21, “s222” };解释运行结果arr-getId();// 第一个学生的id(arr+1)-getId();// 第二个学生的idarr[1].getId();// arr[1]得到的是一个实体而不是一个指针,得到第二个学生的idStudent s3(Student()); 是拷贝构造吗1、这是一个非常经典的C++语法陷阱!这不是拷贝构造,而是一个函数声明!它等价于Student s3(Student (*)());—— 参数类型是一个函数指针,指向一个返回 Student 类型、无参数的函数2、Student s3{Student()}; 这样的才是构造函数3、正确的拷贝构造方式// 创建一个对象Student s1;// 使用已有的实例进行拷贝Students2(s1);Student s3=s1;Student s4{s1};// 使用临时对象进行拷贝Student s3=Student();Student s4=Student(s1);Student s4{Student()};构造函数的特点答:构造函数特点:必须是公有函数,不能有 return析构函数的特点1、必须是共有函数,不能有 return,不能重载2、栈空间下,相同定义域中后创建的先析构,不同定义域中定义域先结束的先析构3、堆空间下,回收时立刻析构,不回收则不析构Student stu[3] = { Student(“A”),Student(“B”),Student(“C”) };涉及到拷贝构造吗答:不会触发临时对象到对象数组元素的拷贝构造,因为进行了返回值优化(RVO)—— 一种编译器优化技术,它让临时对象直接创建在对象数组元素所在的内存空间上,从而省去了拷贝构造,只会触发临时对象的有参构造函数Student s();能够声明一个变量吗答:不行,这会被编译器视为一个函数正确写法classStudent{private:string name;public:Student(){name="None";}Student(string name):name(name){}voiddisplay(){coutnameendl;}};intmain(){// 静态分配的写法Student s1;// 正确写法 触发无参构造// Student s2(); // 错误写法 这会被视为一个函数Students3_1("s3_1");// 正确写法 触发有参构造Student s4={"s4"};// 正确写法 触发有参构造Student arr1[2]{{"s5"},{"s6"}};// 正确写法// 动态分配Student*s9_1=newStudent;// 正确写法,触发无参构造Student*s9_2=newStudent();// 正确写法,触发无参构造Student*s10=newStudent{};// 正确写法,触发无参构造Student*s11=newStudent("s11");// 正确写法,触发有参构造Student*s12=newStudent{"s12"};// 正确写法,触发有参构造Student*arr3=newStudent[2]{{},{"s13"}};// 正确写法return0;}声明和赋值时机的影响结果1、Student s1=s:触发拷贝构造,而不是赋值,因为定义的时候它还没被构造出来,需要先进行构造,而不能直接进行赋值2、Student s; s=xxx; 那么这是先触发Student的无参构造再接上一个赋值语句拷贝构造函数的参数需要加上的原因避免无限递归。根本原因在于如果不加上,则函数在执行时,会复制一份参数(不论是基本数据类型、指针,还是对象等)的副本,而这种复制会触发拷贝构造,进而陷入无限循环拷贝构造函数的参数建议加上 const 的原因答:安全,防止引用的数据被修改为什么临时对象不能绑定到非const引用答:临时对象是右值,代表"一次性使用"的值。非const引用期望与持久状态的左值进行绑定。这个规则会防止出现"修改即将消失的值"的逻辑错误总结:临时对象可以传递给普通的形参例如参数是 Student other,但是如果形参是一个引用的话:Student other,那么为了临时对象能传递进去则必须给形参再加上一个 const 成为 const Student other默认的拷贝构造采用哪种类型的拷贝答:默认拷贝构造函数采用的拷贝方式是浅拷贝浅拷贝的复制方式1、基本元素:直接复制值2、指针类型:复制指针的值,而不复制指向的数据3、数组:逐元素复制4、对象成员:调用该成员的拷贝构造函数’深拷贝和浅拷贝的区别答:深拷贝除了复制指针的值,还会开辟一片新的空间,并将指针指向的数据复制一份出来放在该新空间中静态的特点1、不属于属性,静态成员独立于任何对象存在,不占用对象的内存空间2、共享性:所有对象共享同一个静态成员3、生命周期:从程序启动时就开始存在,到程序结束时销毁4、访问方式:类名::静态、实例.静态、实例.类名::静态静态属性/方法的初始化方式1、在类外进行初始化:类型 类名::属性名=xxx、返回类型 类名::函数名(){...}—— 如果把静态变量放在类里面初始化,它会被重复创建多次,导致编译错误2、静态属性也可以在类内进行初始化:const static 类型 函数名=xxx—— 添加了 const 关键字说明该静态属性无需运行时存储,故允许类内初始化TIP:静态属性必须初始化静态属性/方法的访问方式1、类名::属性名、类名::函数名()2、实例.静态属性、实例.类名::静态属性、实例.静态方法()、实例.类名::静态方法()外联的优点:当类的成员函数众多,实现代码很长时,使用外联可以增加代码的可读性

更多文章