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 ...
随机推荐
- 【BIEE】清除缓存
清除缓存步骤: 1.管理→管理会话→关闭所有游标 2.管理→发出SQL语句:CALL SAPURGEALLCACHE(); 点击发送SQL语句后
- 深入PHP内核之函数和返回值
1.关于返回值,PHP内核中使用了大量的宏来实现,我们先看一个函数 PHP_FUNCTION 宏的定义(Zend/zend_API.h) #define PHP_FUNCTION ZEND_FUNC ...
- PHP实现4种排序算法
1.冒泡排序 冒泡排序其实是基于“交换”.每次从第一个记录开始,一.二两个记录比较,大的往后放,二三两个记录比较...依次类推,这就是一趟冒泡排序.每一趟冒泡排序后,无序序列中值最大的记录冒到序列末尾 ...
- 用curl去探测接口是否正常返回结果,若没有正常返回则触发报警
现有一需求去curl 在香港的一个接口, 返回值有时正常有时报错 connection reset by peer . 思路: 若 执行成功 $?返回 0 , 不成功则返回其他数字 #!/bin/b ...
- HDUOJ----(2064)汉诺塔III
汉诺塔III Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- HDUOJ-----(1072)Nightmare(bfs)
Nightmare Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- JavaScript(select onchange)的网页跳转的简单实现
方法一: <select onchange="goUrl(this.options[this.selectedIndex])"> <option>==& ...
- [Python]网络爬虫(七):Python中的正则表达式教程(转)
接下来准备用糗百做一个爬虫的小例子. 但是在这之前,先详细的整理一下Python中的正则表达式的相关内容. 正则表达式在Python爬虫中的作用就像是老师点名时用的花名册一样,是必不可少的神兵利器. ...
- python练习笔记——丑数的计算
只包含因子2,3,5的正整数被称作丑数,比如4,10,12都是丑数,而7,23,111则不是丑数,另外1也不是丑数.——摘自百度百科 get_num = int(input("请您输入丑数的 ...
- Interface_GL通过gl_interface导入日记账(案例)
2014-06-17 BaoXinjian