C++ 学习笔记 (4) 拷贝构造函数

#include <bits/stdc++.h>
using namespace std ;

class Student {
public:
	int NO ;
	string name ;

	explicit Student ( const int _NO , const string _name ) 
	: NO ( _NO ) , name ( _name ) {
		cout << endl << "构造函数" << endl ;
	}

	void display () const {
		cout << endl << "NO  :  " << NO << "\t" << name << endl ;
	}

	~Student () noexcept {}
} ;

int main () {

	Student One ( 1 , string ( "Jack" ) ) ;
	One.display () ;

	Student Two ( One ) ;          // 拷贝一个副本
	Two.display () ;

	Student Three = One ;          // 拷贝一个副本
	Three.display () ;

	vector < Student > P ;         // 放进容器会调用拷贝构造函数
	P.push_back ( One ) ;
	P[0].display () ;

	vector < Student* > Q ; 
	Q.push_back ( &One ) ;        // 这里没有调用 拷贝构造函数.......因为是指针
	Q[0]->display () ;

	One.name = string ( "Marry" ) ;  // 对指针的操作会作用到原来的内存上
	Q[0]->display () ;

	return 0 ;
}

C++的类有默认的拷贝构造函数,和构造函数一样,如果程序员不声明,编译器自动生成。

容易错的几点是:

1. 容器中放入对象实体,会调用拷贝构造函数

2. 容器中放入对象实体的指针,不会调用拷贝构造函数,因为指针只是地址

3. 容器的一些函数,参数上是 const 类型的,所以,如果自己写拷贝构造函数,参数必须是 const 类型的。

例如, C++ 的 vector : 

push_back ( const value_type & )
要求是 const 类型。

C++ 11 还支持右值引用, push_back ( value_type && )

4. 加 const 可以防止拷贝过程中源对象被修改

5. 加 & 是引用,为了减少拷贝构造函数,因为如果不加引用 &, 传入的参数本身就是一个副本,也要调用拷贝构造函数,所以会无限调用下去

6. 对象实体很大的情况,不建议用拷贝构造函数,开销太大。可以选择用指针,只需要保存一个地址,而且是基类的情况下还可以借助指针实现多态,但指针的操作都是在源对象上操作,这点要注意。

7. 拷贝构造函数,默认先找非 const 类型,再找 const 类型

#include <bits/stdc++.h>
using namespace std ;

class Student {
public:
	int NO ;
	string name ;

	explicit Student ( const int _NO , const string _name ) 
	: NO ( _NO ) , name ( _name ) {
		cout << endl << "构造函数" << endl ;
	}

	void display () const {
		cout << endl << "NO  :  " << NO << "\t" << name << endl ;
	}

	// vector 
	// push_back ( const value_type & )
	Student ( const Student &One ) {   // 容器 push_back 参数是 const 类型
		this->NO = One.NO ;
		this->name = One.name ;
		cout << endl << "参数是 const类型 的拷贝构造函数被调用了" << endl ;
	}

	Student ( Student &One ) {    // explicit 
		this->NO = One.NO ;
		this->name = One.name ;  
		cout << endl << "参数是 普通数据类型 的拷贝构造函数被调用了" << endl ;
	}

	Student ( Student *One ) {
		this->NO = One->NO ;
		this->name = One->name ;
		cout << endl << "参数是 指针类型 的拷贝构造函数被调用了" << endl ;
	}

	~Student () noexcept {}
} ;

int main () {

	Student One ( 1 , string ( "Jack" ) ) ;
	One.display () ;

	Student Two ( One ) ;          // 拷贝一个副本
	Two.display () ;

	vector < Student > P ;         // 放进容器会调用拷贝构造函数
	P.push_back ( One ) ;
	P[0].display () ;

	vector < Student* > Q ; 
	Q.push_back ( &One ) ;        // 这里没有调用 拷贝构造函数.......因为是指针
	Q[0]->display () ;

	One.name = string ( "Marry" ) ;  // 对指针的操作会作用到原来的内存上
	Q[0]->display () ;

	return 0 ;
}



猜你喜欢

转载自blog.csdn.net/nishisiyuetian/article/details/80035956