C++对象的构造、析构与拷贝构造
今天下午在研究虚函数的时候遇到了一个问题,觉得很有意思,记录一下。
先看代码:
class Base
{
public:
Base(int value)
{
m_nValue = value;
cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl;
} ~Base()
{
cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl;
}
private:
int m_nValue;
}; int main()
{
Base b();
(Base)b;
return ;
}
打印结果:

为什么会调用两个析构函数?一个析构函数是可以理解的,为什么要调用两次?
其实这里是调用了一次拷贝构造函数。调整一下代码
class Base
{
public:
Base(int value)
{
m_nValue = value;
cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl;
}
//新增部分
Base(const Base& b)
{
this->m_nValue = b.m_nValue;
cout << "object(" << this << "){" << this->m_nValue << "} is copy constructing!" << endl;
}
//新增部分结束!
~Base()
{
cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl;
}
private:
int m_nValue;
}; int main()
{
Base b();
(Base)b;
return ;
}
执行结果:

注意红框里边标注的!(Base)b隐式的调用了拷贝构造函数和析构函数。
(Base)b的操作这样看起来不是很舒服,我们把再修改一下代码
void fun(Base b)
{
//do nothing
}
int main()
{
Base b();
fun(b);
return ;
}
执行结果:

b在进入fun这个函数的时候,发生了拷贝构造到析构的操作。这样就很容易理解刚开始的问题:为什么会出现两次析构函数。
再修改一下代码,验证一下:
void fun(Base& b)
{
//do nothing
cout << "fun" << endl;
}
int main()
{
Base b();
fun(b);
return ;
}
执行结果。

这也就是为什么要用引用 Base& b 而直接使用 Base b 的原因了。当然,最好还是加上const。
上述就是这个问题的记录
C++对象的构造、析构与拷贝构造的更多相关文章
- C++基本函数的调用优化(构造、拷贝构造、赋值)
合理的函数可提升时间和空间的利用率 //Test1.h #include<iostream> using namespace std; struct ST { private: int a ...
- C++之旅:拷贝构造与友元
拷贝构造与友元 拷贝构造是在构造一个对象的时候将已有对象的属性拷贝给新的对象:友元可以让一个类的所有属性(主要是private)对特定的类开放 拷贝构造 如果没有复写拷贝构造函数,系统会帮我们默认生成 ...
- C++ //拷贝构造函数调用时机//1.使用一个已经创建完毕的对象来初始化一个新对象 //2.值传递的方式给函数参数传值 //3.值方式返回局部对象
1 //拷贝构造函数调用时机 2 3 4 #include <iostream> 5 using namespace std; 6 7 //1.使用一个已经创建完毕的对象来初始化一个新对象 ...
- 构造 & 析构 & 匿名对象
以前仅知道创建对象,但对匿名对象的了解基本为0. 通过阅读google chromium源代码 中关于 log 的使用,查阅相关资料,了解了一下匿名对象,予以记录. 什么是匿名对象 匿名对象可以理 ...
- STL——容器(Set & multiset)的默认构造 & 带参构造 & 对象的拷贝构造与赋值
1. 默认构造 set<int> setInt; //一个存放int的set容器. set<float> setFloat; //一 ...
- C++ 构造函数、析构函数、拷贝构造、赋值运算符
之所以要把它们放在一起,是因为在使用C/C++类语言的时候,很容易混淆这几个概念(对Java来说完全没有这样的问题,表示Javaor完全没有压力). 先建立一个测试类(包含.h和.cpp) //~ P ...
- Effective C++笔记:构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- Effective C++ 2.构造 析构 赋值运算
//条款07:为多态基类声明virtual析构函数 // 1.若基类的析构函数不定义为虚函数,由于基类的指针或引用可以指向派生类的对象,则在删除基类对象的时候可能会出错,导致破坏数据结构. // 2. ...
- C++类构造析构调用顺序训练(复习专用)
//对象做函数参数 //1 研究拷贝构造 //2 研究构造函数,析构函数的调用顺序 //总结 构造和析构的调用顺序 #include "iostream" using namesp ...
随机推荐
- VR外包—长年承接虚拟现实项目和AR外包游戏、软件(北京动点飞扬软件)
VR外包AR外包公司(虚拟现实外包公司)承接虚拟现实项目开发(企业.教育.游戏) 可公对公签正规合同,开发票. 我们是北京的公司.专业团队,成员为专业 VR/AR 产品公司一线开发人员,有大型产品开发 ...
- angular --- s3core移动端项目(二)
product-ctrl.js angular.modules('myApp').controller('ProductCtrl',['$scope','$rootScope','$timeout', ...
- DAY9 函数
一.脚本文件的执行 1.存放当前文件作为脚本文件执行的参数们:[‘当前文件的绝对路径’,手动传入的参数们] 2.脚本文件执行:直接用python解释器运行该文件 print(sys.argv) # ...
- (19)ThreadPoolExecutor线程池
# 线程池 # 实例化线程池 ThreadPoolExcutor (推荐cpu_count*(n+1)) # 异步提交任务 submit / map # 阻塞直到任务完成 shutdown # 获取子 ...
- hihocoder #1044 : 状态压缩·一 状压DP
http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...
- 『Python CoolBook』C扩展库_其六_从C语言中调用Python代码
点击进入项目 一.C语言运行pyfun的PyObject对象 思路是在C语言中提供实参,传给python函数: 获取py函数对象(PyObject),函数参数(C类型) 获取GIL(PyGILStat ...
- [lightoj P1306] Solutions to an Equation
[lightoj P1306] Solutions to an Equation You have to find the number of solutions of the following e ...
- Module(模块)
1.每个Angular至少有一个根Module 2.Module时一个带有@NgModule装饰符的类 3.最简单的Module import { NgModule } from '@angular/ ...
- Kotlin(一)
Kotlin(一) 写在前面: 参考资料: <Kotlin官方文档><Kotlin for Android 开源中文版> 准备工作: Android-Studio2.x:添加K ...
- 关于c#连接数据库的代码
using System;using System.Collections.Generic;using System.Data;using System.Data.SQLite;using Syste ...