复制构造函数
来源:互联网 发布:ubuntu开机启动程序 编辑:程序博客网 时间:2024/05/22 02:00
假设定义了一个ClassDemo的类
class ClassDemo{public: ClassDemo(); ClassDemo(int num); ~ClassDemo();private: int _num;};
在main函数中
CLassDemo demo = 10;demo = 20;
第一句话代表的并不是赋值,此时会调用转换构造函数。
第二句话会调用默认的赋值函数:先通过转换构造函数创建一个临时的对象,再将该对象传递给默认的赋值函数,最后析构该临时对象。
请参考构造函数讲解
如果在main函数中
ClassDemo demo = 10;ClassDemo demo1 = demo;
第二句话并非一个赋值,此时它会调用复制构造函数。
这是复制构造函数的函数原型,它会将类中的所有成员变量复制到对象中
ClassDemo(const ClassDemo &other);
复制构造函数的形参必须是一个引用,否则编译是无法通过的。如果形参不是一个引用的话,此时会产生无限递归,因为将一个对象传递到复制构造函数中时,此时会为该对象产生一个副本,而产生副本的过程就会调用复制构造函数,此时便产生了无限递归。
举个例子:
void f1(ClassDemo demo)
{
}
void f2(ClassDemo &demo)
{
}
在main函数调用这两个函数产生的结果是不一样的
ClassDemo demo;f1(demo);f2(demo);
程序在执行到f1的时候,因为f1的形参为类的对象。此时首先会调用复制构造函数创建这个对象。然后才会进入f1函数执行函数体的部分。在f1执行完之后该对象会被析构。
程序执行到f2的时候,因为传递的是一个对象的引用,此时不会有新的对象产生,复制构造函数不会执行,此时会直接执行f2函数体部分,也不会有析构函数的调用。
学到这里可以知道,在一个空类中有4个函数会被默认生成。
默认构造函数
默认析构函数
默认复制构造函数
默认赋值函
关于复制构造函数的使用:
class MyString{pubilc: MyString(char *str):_len(strlen(str)) { new char[_len + sizeof(char)]; strcpy(_str, str); } ~MyString() { if(_str) delete[]_str; } MyString(MyString &other) { _str = other._str; } MyString& operator=(MySting &other) { _len = other._len; _str = other._str; return *this; } char *GetString() { return _str; }private: char *_str;};
int main(){ MyString demo = "I Have Apple"; MyString demo1 = demo; std::cout << demo1.GetString(); demo1 = "I Have Pen"; std::cout << demo1.GetStrinf(); return 0;}
打印的结果为:
这是因为在执行demo1 = “I Have Pen”的时候会调用默认的赋值函数。
默认的赋值函数首先会创建一个临时的对象temp
然后会将该临时对象的值给demo1
即为:
MyString operator=(const MyString& temp){ _str = temp._str; _len = temp._len;}
在该赋值函数结束后,临时对象temp会被析构掉。所以指向temp._str的空间会被delete。此时的demo1. _str所指向的空间被delete了,demo1. _str也就变成了野指针,所以打印出来的结果自然也是未知的。在vs编译器的dubug下这段空间会被填充成0xdddddddd。
所以当我们类的成员变量中存在指针的时候,使用默认的复制构造函数和默认的赋值函数时就会存在风险
这种直接对指针的赋值称为浅拷贝。使得指针易被delete,在这种情况下应当使用深拷贝来维护该成员变量的生命周期。
MyString(MyString &other){ delete[]_str; _len = other._len; _str = new char[_len + sizeof(char)]; strcpy(_str, other._str);}MyString& operator=(MySting &other){ delete[]_str; _len = other._len; _str = new char[_len + sizeof(char)]; strcpy(_str, other._str); return *this;}
深拷贝实质上是维护了对象中所有属性的生命周期。使其生命周期和对象是同步的。
- 构造函数 复制构造函数
- 深复制-复制构造函数
- 关于复制构造函数
- 关于复制构造函数
- 关于复制构造函数
- 关于复制构造函数
- 关于复制构造函数
- 学习复制构造函数
- 复制构造函数
- 复制构造函数
- 复制构造函数
- 复制构造函数
- 复制构造函数总结
- 复制构造函数
- 复制构造函数
- C++复制构造函数
- 复制构造函数实例
- 复制构造函数
- ThreadLocal内存泄露(下)
- exec函数族的作用与讲解
- 【android学习】SharedPreferences详解
- 带你玩转javaWeb之七-使用JDBC完成CRUD的操作
- ROS 模拟激光仿真数据 使用stage进行仿真 在stage中控制两个机器人
- 复制构造函数
- 【网络流24题】最小路径覆盖问题
- 1002. A+B for Polynomials (25)
- Thread之脏读
- windows2003 IIS6 部署MVC3和MVC4程序
- Android NDK的简单例子
- react -native 自定义按钮
- vi编辑器的使用 linux命令
- ++i和i++的根本区别