特殊的构造方式
一、拷贝构造函数
1什么是拷贝构造函数
是基于构造函数的更高级的构造方式,着眼于拷贝二字,即相当于复制.
是c++特有的一种构造函数,用于基于同一个类的一个对象去创造和初始化一个对象.
2语法
~~~c++
#include<iostream>
using namespace std;
class MyClass
{
public:
int num;
MyClass(MyClass &x);//默认拷贝构造函数
~MyClass();
void show();//显示属性的构造函数
MyClass(int hp);
private:
int hp;
};
MyClass::MyClass(MyClass &x)
{
cout << "调用了拷贝构造函数(默认的)" << endl;
this->hp = x.hp;//x是一个对象,将hp赋值给我的hp.
}
MyClass::MyClass(int hp)
{
cout << "调用了带参构造函数" << endl;
this->hp = hp;
}
MyClass::~MyClass()
{
cout << "调用了析构函数" << endl;
}
void MyClass::show()
{
cout << "调用了显示属性的函数" << endl;
cout << "hp= " << this->hp << endl;
}
int main()
{
MyClass monster(100);
monster.show();
MyClass monster1(monster);
monster1.show();
system("pause");
return 0;
}
~~~
3调用时机
1.函数的参数是类的对象时
~~~c++
#include<iostream>
using namespace std;
class MyClass
{
public:
int num;
MyClass(MyClass &x);
~MyClass();
void show();
MyClass(int hp);
void test(MyClass monster);
private:
int hp;
};
MyClass::MyClass(MyClass &x)
{
cout << "调用了拷贝构造函数(默认的)" << endl;
this->hp = x.hp;//x是一个对象,将hp赋值给我的hp.
}
MyClass::MyClass(int hp)
{
cout << "调用了带参构造函数" << endl;
this->hp = hp;
}
MyClass::~MyClass()
{
cout << "调用了析构函数" << endl;
}
void MyClass::show()
{
cout << "调用了显示属性的函数" << endl;
cout << "hp= " << this->hp << endl;
}
void MyClass::test(MyClass monster)
{
cout << "调用了void MyClass::test(MyClass monster)函数" << endl;
}
```cpp
int main()
{
MyClass monster(100);
monster.show();
MyClass monster1(monster);
monster1.show();
monster1.test(monster);
system("pause");
return 0;
}
```cpp
2函数的返回值时类的对象
```cpp
```cpp
```cpp
```cpp
```cpp
```cpp
```cpp
```cpp
```cpp
~~~c++
#include<iostream>
using namespace std;
class MyClass
{
public:
int num;
MyClass(MyClass &x);
~MyClass();
void show();
MyClass(int hp);
void test(MyClass monster);
MyClass test1();
private:
int hp;
};
MyClass::MyClass(MyClass &x)
{
cout << "调用了拷贝构造函数(默认的)" << endl;
this->hp = x.hp;//x是一个对象,将hp赋值给我的hp.
}
MyClass::MyClass(int hp)
{
cout << "调用了带参构造函数" << endl;
this->hp = hp;
}
MyClass::~MyClass()
{
cout << "调用了析构函数" << endl;
}
void MyClass::show()
{
cout << "调用了显示属性的函数" << endl;
cout << "hp= " << this->hp << endl;
}
void MyClass::test(MyClass monster)
{
cout << "调用了void MyClass::test(MyClass monster)函数" << endl;
}
MyClass MyClass::test1()
{
cout << "调用了void MyClass::test1()函数" << endl;
return *this;
}
int main()
{
MyClass monster(100);
monster.show();
MyClass monster1(monster);
monster1.show();
monster1.test(monster);
printf("\n");
monster1.test1();
return 0;
}
```
```
```
```
```
```
```
```
3.使用一个对象给另一个对象初始化
4.使用一个对象去构造另一个对象
## 二、深拷贝与浅拷贝
### 1什么是浅拷贝
浅拷贝即全部照抄
### 2什么是深拷贝
当你在定义拷贝构造函数的时候,如果需要从另一个那里去复制一个数据,如果你直接复制,因为你们两个的指针都是指向同一块内存的,当释放内存时,必然有一个会先释放,而导致另一个指向为空,当再次释放是,程序就会报错,所以我们需要一个深拷贝
```cpp
```cpp
```cpp
```csharp
```cpp
```cpp
~~~c++
#include<iostream>
#include<assert.h>
using namespace std;
class monster
{
public:
int hp;
int mp;
int *p;
monster();
~monster();
//默认拷贝构造
//monster(monster &monster)
//{
// this->hp = hp;
// this->mp = mp;
// this->p = monster.p;//这样就会导致上述情况
//}
//深拷贝
monster(monster&monster)
{
this->hp = hp;
this->mp = mp;
this->p = new int;
*p = *monster.p;
}
};
monster::monster()
{
p = new int(100);
}
monster::~monster()
{
assert(p != nullptr);//断言,即会出现上述情况
delete p;
p = nullptr; }
int main()
{
monster monster;
cout << *monster.p << endl;
*monster.p = 99;
cout << *monster.p << endl;
system("pause");
return 0;
}
~~~
## 三、一些细节问题
1拷贝构造函数必须用&传递,否则引起拷贝函数的递归调用
2.拷贝构造函数可以调用类里面的私有成员(因为拷贝构造函数也是属于类的)
3.一个类可以有多个拷贝构造函数(因为函数可以重载).