特殊的构造方式

特殊的构造方式

一、拷贝构造函数

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.一个类可以有多个拷贝构造函数(因为函数可以重载).
上一篇:PASCAL VOC2012数据集讲解与制作自己的数据集使用labelimg


下一篇:YOLO