c++深/浅拷贝 && 构造函数析构函数调用顺序练习题
1.深/浅拷贝
编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝。浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟内存,这就会使得程序运行出现内存错误,如此,当对象析构的时候,会delete多次同一块内存区域,发生错误。这也就是为什么,必要的时候需要我们自己编写拷贝构造函数和重载赋值运算符,让它变成深拷贝,深拷贝即在copy指针的时候不是简单做值copy,而是还要开辟内存。
2.构造函数析构函数调用顺序练习题
如果下面的调用过程不用编译器都能快速知道,那么拷贝构造函数和析构函数的调用过程就基本掌握了。
#include<iostream>
#include<string>
using namespace std;
class Copy_construction {
public:
Copy_construction(int a,int b,int c)
{
this->a = a;
this->b = b;
this->c = c;
cout << "这是Copy_constructiond的有默认参数的构造函数! "<<this->a<<" "<<this->b<<" "<<this->c<<endl;
} ~Copy_construction()
{
cout << "Copy_construction对象被析构了! "<<this->a << " " << this->b << " " << this->c << endl;
} int getC()
{
return a;
}
private:
int a;
int b;
int c; }; class Test {
public:
Test():obj1(,,),obj2(,,),m()
{
cout << "Test() 构造函数\n";
}
~Test()
{
cout << "Test 对象析构了\n";
}
Test(const Test &obj):obj1(,,),obj2(,,),m()
{
cout << "Test(const Test &obj) 拷贝构造函数调用了 \n";
} Copy_construction obj1;
Copy_construction obj2;
int m;
};
void play_empty(Test mytest)
{
cout << "play_empty(Test mytest) " << mytest.obj1.getC()<<endl;
} int run()
{
Test mytest;
play_empty(mytest);
return ;
}
int main()
{ run();
cout << "hello world!\n";
return ;
}
运行结果:

summary:
最好使用构造函数的初始化列表,而不是用赋值,虽然c++11支持类内初始值,但是目前大多项目都是不使用类内初始值而用构造函数初始化列表代替,可能是为了维护之前的代码吧。初始化列表要注意的一点是,成员初始化顺序最好与它们在类内声明中出现的顺序一致。比如:
calss X{
int i;
int j;
public:
X(int val) :j(val),i(j) {}//编译器先初始化i,因为i在j之前出现在类中,这会让一个垃圾值j去初始化i。所以要特别注意这一点。
};
比较友好的编译器可能会对构造函数初始值列表中的数据成员顺序与这些成员的声明顺序不一致时发出警告。Qt creator和gcc 5.4.0会发出警告,vs2015则不会^_^。
如果类的属性有const修饰的标识符,如const int a;此时可以采用类内初始值,但是为了兼容c++11之前的代码,我们采用const int a;然后的a的值在类的构造函数初始值列表上完成初始化,不能在构造函数内部给const的标识符赋值,只能在初始值列表处初始化。
c++深/浅拷贝 && 构造函数析构函数调用顺序练习题的更多相关文章
- c++构造函数析构函数调用顺序
#include <iostream> using namespace std; class A { public: A () { cout<<"A 构造 " ...
- 12.C++-构造函数与析构函数调用顺序,const成员函数,const对象
单个对象创建时,构造函数的调用顺序 1.首先判断该对象的类是否拥有父类,若有则先调用父类的构造函数 2.判断该对象的成员是否是其它类的成员,若是则调用成员变量的构造函数(调用顺序和声明顺序相同) 3. ...
- C++类的继承中构造函数和析构函数调用顺序例子
/*当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止.简而言之,对象是由“底层向上”开始构造的.因为,构造函数 ...
- C++单继承的构造函数和析构函数调用的顺序
1.继承构造函数调用顺序以及销毁的过程 先调用父类的构造函数,在调用子类的构造函数,析构函数调用相反.
- C++构造函数和析构函数调用虚函数时都不会使用动态联编
先看一个例子: #include <iostream> using namespace std; class A{ public: A() { show(); } virtual void ...
- java初始化构造函数调用顺序
类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值: (2)调用父类构造函数: (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式: (4)调用本身构造函数. 例子 ...
- C++成员变量、构造函数的初始化顺序 [转]
C++成员变量.构造函数的初始化顺序 一.C++成员变量初始化 1.普通的变量:一般不考虑啥效率的情况下 可以在构造函数中进行赋值.考虑一下效率的可以再构造函数的初始化列表中进行 2.static 静 ...
- C++继承中析构函数 构造函数的调用顺序以及虚析构函数
首先说说构造函数.大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数, ...
- iOS 浅谈:深.浅拷贝与copy.strong
深.浅拷贝 copy mutableCopy NSString NSString *string = @"汉斯哈哈哈"; // 没有产生新对象 NSString *copyStri ...
随机推荐
- linux软硬链接
ln分为软链接和硬链接 1.软连接 -s ln -s /mnt/hgfs/SHARE hvshare2 相当于在当前目录下新建一个名为hvshare2的快捷方式指向/mnt/hgfs/SHARE路 ...
- 微信小程序-自定义底部导航
代码地址如下:http://www.demodashi.com/demo/14258.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- hdu1690Bus System--解题报告
题意:有一个公交系统的收费标准例如以下表: 然后问:给出 这些L1~4 & C1~4的值,然后 N个站.列出每一个站的X坐标.然后询问M次,问两个站台的最小花费 题解:那么这里非常明显是最短路 ...
- HDUOJ Children’s Queue
Children’s Queue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 在python中使用静态方法staticmethod
静态方法: 静态方法是类中的函数,不需要实例.静态方法主要是用来存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作.可以理解为将静态方法存在 ...
- Python 绘图库的使用:matplotlib
Matplotlib 官方API地址:https://matplotlib.org/ 例子: import matplotlib.pyplot as plt num_list=[1.5,0.6,7.8 ...
- JavaScript 设计模式之代理模式
一.代理模式概念解读 1.代理模式概念文字解读 代理,顾名思义就是帮助别人做事,GOF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象 ...
- php 内存管理
内存是计算机⾮常关键的部件之⼀,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以⽤于存储计算数据,⽽⼤部分的数据都是存储在内存中的,程序运⾏都是在内存中进⾏的.和CPU计算能⼒⼀样, 内存也是 ...
- Android 手机震动功能实现
1首先在AndroidManifest.xml中添加震动权限 <uses-permission android:name="android.permission.VIBRATE&quo ...
- iOS网络框架 AFNetworking
-(void)GetActivationUser{ NSString *url = @"http://app.xxxx.com/music/search?key=%E9%AC%BC%E5%9 ...