只有单个形参,而且该形参是本类类型对象的引用(常用const修饰),这样的构造函数称为复制构造函数。与默认的构造函数一样,复制构造函数由编译器隐式调用。
如果我们没有定义复制构造函数,编译器就会为我们合成一个。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数,合成复制构造函数将逐个成员初始化。
下面是代码:Student.h头文件
#if !defined(AFX_STUDENT_H__334531D3_6CD2_48F8_BDE2_98A82D166466__INCLUDED_) #define AFX_STUDENT_H__334531D3_6CD2_48F8_BDE2_98A82D166466__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <string> class Student { public: Student(); Student(Student&); virtual ~Student(); std::string name; unsigned int no; }; #endif
Student.cpp源文件:
#include "Student.h" Student::Student() { } Student::~Student() { } Student::Student(Student& s) { this->name=s.name; this->no=s.no; }
Main.cpp源文件中包含main函数:
#include <iostream> #include "Student.h" using namespace std; int main() { Student s; s.name="zhy_cheng"; s.no=32; Student liu(s); //这里默认调用复制构造函数 cout<<liu.name<<endl<<liu.no<<endl; return 0; }
当自己定义了一个复制构造函数的时候,编译器就不再提供默认的复制构造函数。
我们可以在复制构造函数中做自己的操作,如给某个成员定义默认的值。我键复制构造函数改成下面的样子:
Student::Student(Student& s) { this->name="临江仙"; this->no=s.no; }
打印出下面的值:
临江仙 32
禁止复制
如果需要禁止复制的话,必须要显示的声明其复制构造函数为private类型,因为如果不声明复制构造函数,编译器就会提供一个默认的复制构造函数。如果复制构造函数是私有的,将不允许用户代码复制该类类型的对象,编译器将拒绝任何进行复制的尝试。
然而,类的成员和友元仍然可以进行复制。如果连友元和类成员中的复制也要禁止,可以声明一个private类型的复制构造函数,但不对其定义。声明而不定义成员函数是合法的,但是,使用未定义成员的任何尝试将导致连接失败。通过声明但不定义private复制构造函数,可以禁止任何复制类类型对象的尝试:用户代码中的复制尝试将在编译时标记为错误,而成员函数和友元中的复制尝试将在链接时导致错误。
大多数类应定义复制构造函数和默认构造函数
不定义复制构造函数和/或默认构造函数,会严重局限内的使用。不允许复制的类的对象只能作为引用传递给函数或从函数返回,他们也不能用作容器的函数。如果定义了复制构造函数,也必须定义默认构造函数。