当前位置: 首页 > ai >正文

C++入门自学Day5-- c++类与对象(面试题)

c++类与对象往期回顾:

        c++类与对象(友元)
        c++类与对象(类的初始化和静态成员)
        c++类与对象(赋值运算符与拷贝构造)
        c++类与对象(拷贝构造)
        c++类与对象(构造和析构函数)
        c++类与对象(初识2)
        c++类与对象(初识)

【 面试题】

        问题一:

        1、设已经有A,B, C, D4个类的定义,程序中A, B, C, D析构函数调用顺序为(B);

C c;int main(){A a; B b;static D d;return 0;}

选项:

A. D B A C         B. B A D C       C. C D B A      D.  A B D C


解题思路:

我们定义一个栈类用来查看栈释放的地址的先后顺序来--> 判断A, B, C, D析构函数调用顺序

class Stack{public:Stack(){_arr = (int*)malloc(sizeof(int)*_capacity);cout<<"malloc "<<_arr<<endl;};~Stack(){cout<<"free "<<_arr<<endl;_arr = nullptr;_size = 0;_capacity = 0;};private:int* _arr;int _size;int _capacity;
};
Stack C;
int main(){Stack A;Stack B;static Stack D;
}

输出描述:

对象的构造顺序

malloc 0x158e05e70  --> C
malloc 0x158e05e10  --> B
malloc 0x118e00000 --> A
malloc 0x158e05fc0  --> D


对象的析构顺序

free 0x118e00000 --> B
free 0x158e05e10 --> A
free 0x158e05fc0 --> D
free 0x158e05e70 --> C


总结:

类别

构造时机

析构时机

存储位置

全局变量

程序开始前(main 前)

程序结束时最后

.data/.bss

局部变量

执行到定义处时

离开作用域(如 main 结束)

栈(stack)

static局部变量

第一次执行到定义时构造

程序结束时(在全局之前)

.data


        问题二:

         2、以下代码共调用多少次拷贝构造函数:(D)

Widget f(Widget u){Widget v(u);Widget w = v;return w;
}
int main(){Widget x;Widget y = f(f(x));
}

选项分析:

A. 1         B. 3     C. 5    D.  7


解题思路:

Widget x;

 1、首先,把 f(f(x)) 当作整体例如 Widget F,则 Widget y = Widget F。而这里,由于 y 这个对象先前并不存在,所以这里的 “=”并不是赋值运算符,而是发生拷贝构造 --> 1次。

  2、 单独看f(x)。f(x)这里把x传入拷贝构造函数,调用拷贝构造 -->2次,然后函数里面,Widget v(u) 调用一次拷贝构造--> 3次.然后 Widget w = v;w先前不存在,这里还是调用拷贝构造 --> 4次,最后这里是传值返回而不是传引用和指针,会进行临时变量的拷贝,又要调用拷贝构造-->5次

3、 看f(f(x)) -->把括号里的f(x)当作一个整体,结果就相当于在调用一次f(x) -->再调用4次拷贝构造 总共9次。

4、但是编译器会对代码进行优化,第4次和第5次会被合二为一,优化成为一个对象,编译器在一个连续的多次的拷贝构造都会被优化成一个拷贝。优化都发生在返回和传参中。所以最终结果是7次。这是在vs2013版本下


vscode代码可视化:

class Widget{
public:Widget(){};Widget (const Widget& w){cout<<"call the copy_constructor!"<<endl;}};Widget f(Widget u){Widget v(u);Widget w = v;return w;
}   int main(){Widget x;Widget y = f(f(x));
}

输出结果:调用五次拷贝构造。
call the copy_constructor!
call the copy_constructor!
call the copy_constructor!
call the copy_constructor!
call the copy_constructor!

对于vscode编译器:

编译器启用了 RVO(Return Value Optimization) 或 Copy Elision(复制省略)

✅ 编译器优化行为:
  • 最终返回的 w(即 return w;)→ 会直接构造到调用者 y 的位置,不再调用拷贝构造。

  • 也有可能优化掉中间的临时对象赋值。

步骤

说明

是否触发拷贝构造

1

x 传入 f(x)

✅ 第一次

2

Widget v(u)

✅ 第二次

3

Widget w = v

✅ 第三次

4

return w(传值返回)

✅ 第四次(可能优化)

5

上一个结果传入 f(...)

✅ 第五次

6

return w 构造给 y

❌(优化成直接构造)

http://www.xdnf.cn/news/16800.html

相关文章:

  • 苹果MAC 安卓模拟器
  • HarmonyOS 开发:基于 ArkUI 实现复杂表单验证的最佳实践
  • CS课程项目设计7:基于Canvas交互友好的五子棋游戏
  • Pyspark的register方法自定义udf函数
  • Mysql在页内是怎么查找数据的?
  • Web 开发 10
  • Redis 核心概念、命令详解与应用实践:从基础到分布式集成
  • pyqt5显示任务栏菜单并隐藏主窗口,环境pyqt5+vscode
  • JVM 03 类加载机制
  • Python打卡Day30 模块和库的导入
  • LeetCode 刷题【26. 删除有序数组中的重复项、27. 移除元素、28. 找出字符串中第一个匹配项的下标】
  • vue2一种快速导入 Element UI(即 Element 2.x)方式
  • ARM Cortex-M异常处理高级特性详解
  • MCP Agent 工程框架Dify初探
  • 【C++】类和对象(2)
  • AI Agent开发学习系列 - LangGraph(4): 有多个输入的Graph(练习解答)
  • 设计模式篇:在前端,我们如何“重构”观察者、策略和装饰器模式
  • Android 运行 deno 的新方法 (3): Termux 胖喵安初
  • vue3pinia
  • 深度学习核心:卷积神经网络 - 原理、实现及在医学影像领域的应用
  • vue3 新手学习入门
  • Elasticsearch 混合检索一句 `retriever.rrf`,把语义召回与关键词召回融合到极致
  • Agents-SDK智能体开发[5]之集成MCP进阶
  • 【vue】创建响应式数据ref和reactive的区别
  • Ⅹ—6.计算机二级综合题23---26套
  • 两个服务之间的大规模数据推送
  • TOGAF指南1
  • Thymeleaf 模板引擎原理
  • 网站QPS多少才算高并发
  • c++和python联合编程示例