热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

请大神帮忙看下这个程序

#include<iostream>#include<stack>usingnamespacestd;classA{public:A(intelem
#include 
#include 
using namespace std;

class A
{
public:
A(int element)
{
a = element;
cout<<"construct"< }
~A()
{
cout<<"end"< }
void print()
{
cout< }
private:
int a;
};

int main()
{
A a1(1),a2(2);
stack stack1;
stack1.push(a1);
stack1.push(a2);
A &data = stack1.top();
stack1.pop();
data.print();
return 0;
}


有两个问题:
1、构造两个对象,构造函数调用2次,析构函数为什么会调用4次呢?
2、stack1.pop()后,a2对象被析构了,那为什么它的引用data还能够调用成员函数print()呢?析构后对象内存不应该释放才对嘛?
本人c++新手,还请大神们帮忙解答一下,谢谢!

10 个解决方案

#1


1. 有两个对象是通过调用A类的复制构造函数生成的。

2. 
a、 此时a2还没有析构,它的作用域是main函数,在main函数结束时才会调用它的析构函数
b、 push 操作会复制对象,引用的并不是a2,而是stack中复制生成的副本

#2


引用 1 楼 mougaidong 的回复:
1. 有两个对象是通过调用A类的复制构造函数生成的。

2. 
a、 此时a2还没有析构,它的作用域是main函数,在main函数结束时才会调用它的析构函数
b、 push 操作会复制对象,引用的并不是a2,而是stack中复制生成的副本

恩,感谢您的回复,也就是说push时调用了类A的复制构造函数,其push只是原对象的一个副本。
不过还有个问题,data引用的是a2的副本,暂且叫它a2_temp,那pop()之后a2_temp会被析构才对,那为什么data.print()还能够执行呢

#3


push的时候传的是引用,没有发生复制啊,奇怪了

#4


http://bbs.csdn.net/topics/390472811

引用 2 楼 xc889078 的回复:
Quote: 引用 1 楼 mougaidong 的回复:

1. 有两个对象是通过调用A类的复制构造函数生成的。

2. 
a、 此时a2还没有析构,它的作用域是main函数,在main函数结束时才会调用它的析构函数
b、 push 操作会复制对象,引用的并不是a2,而是stack中复制生成的副本

恩,感谢您的回复,也就是说push时调用了类A的复制构造函数,其push只是原对象的一个副本。
不过还有个问题,data引用的是a2的副本,暂且叫它a2_temp,那pop()之后a2_temp会被析构才对,那为什么data.print()还能够执行呢

#5


传的是引用不假,但是,你有看过push的实现吗?

引用 3 楼 henry3695 的回复:
push的时候传的是引用,没有发生复制啊,奇怪了

#7


1、两个push其实是构造了两个对象
2、pop后可以访问是因为,对象析构后,只是告诉系统此对象已经无效了,但是数据的内存值还在 的,等到下次用到这块内存的时候,直接把这块内存使用了,这样做貌似好偷懒,其实是提高了效率,少了一次内存操作,只是个人推测

#8



A test(A TT)
{
TT.print();
return TT;
}


在加点,看看调用这个要做几次拷贝

#9


引用 8 楼 henry3695 的回复:

A test(A TT)
{
TT.print();
return TT;
}


在加点,看看调用这个要做几次拷贝

这应该是调用两次复制拷贝,一次是形参值传递那里,另一次是return那里,所以会执行两次复制拷贝函数和两次析构函数

#10


计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

推荐阅读
  • 微服务架构详解及其入门指南
    本文详细介绍了微服务的基本概念、发展历程、与传统架构的区别及优势,并探讨了适合采用微服务架构的场景。此外,文章还深入分析了几个主流的微服务开发框架,特别是Spring Cloud的组成和特点。 ... [详细]
  • 本文介绍了iOS应用开发的主要框架,包括Foundation、UIKit、CoreData及CoreGraphics等,并探讨了开发iOS应用所需的硬件和软件环境,以及推荐的编程语言。 ... [详细]
  • 电子与正电子的相互作用
    本文探讨了电子与正电子之间的基本物理特性及其在现代物理学中的应用,包括它们的产生、湮灭过程以及在粒子加速器和宇宙射线中的表现。 ... [详细]
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • 拖拉切割直线 ... [详细]
  • UVA 401 - 镜像回文字符串
    本题探讨了如何判断一个字符串是否为普通回文、镜像回文或两者都不是。通过特定的字符映射表来实现字符串的镜像转换,并根据转换后的结果进行分类。 ... [详细]
  • POJ2226 二分图最小覆盖问题
    在一个大小为n×m的网格中,部分单元格为泥泞状态,其余为干净。目标是使用宽度固定为1但长度可变的木板覆盖所有泥泞单元格,且不覆盖任何干净单元格。木板允许重叠。本问题通过构建二分图并求其最小覆盖来解决。 ... [详细]
  • 死锁的概念“死锁”指的是:多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源 ... [详细]
  • 大数据SQL优化:全面解析数据倾斜解决方案
    本文深入探讨了大数据SQL优化中的数据倾斜问题,提供了多种解决策略和实际案例,旨在帮助读者理解和应对这一常见挑战。 ... [详细]
  • iOS 面试实战:15 道经典面试题及解析
    本文精选了15道iOS面试题,并提供了详细的解答思路。旨在帮助开发者更好地准备面试,避免因准备不足而导致的紧张和焦虑。 ... [详细]
  • 利用Executor框架管理线程池
    本文介绍了如何使用Executor框架来管理和创建线程池,包括不同的线程池类型及其应用场景,以及如何通过Executors工厂类创建不同类型的Executor实例。 ... [详细]
  • 本文详细介绍了MySQL表分区的概念、类型及其在实际应用中的实施方法,特别是针对Zabbix数据库的优化策略。 ... [详细]
  • 本文深入探讨了锚点技术的应用与实现,通过十个关键点帮助读者全面理解锚点在网页设计中的作用。 ... [详细]
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • Activity跳转动画 无缝衔接
    Activity跳转动画 无缝衔接 ... [详细]
author-avatar
Pri_颖颖_773
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有