只有单个形参,而且该形参是本类类型对象的引用(常用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复制构造函数,可以禁止任何复制类类型对象的尝试:用户代码中的复制尝试将在编译时标记为错误,而成员函数和友元中的复制尝试将在链接时导致错误。
大多数类应定义复制构造函数和默认构造函数
不定义复制构造函数和/或默认构造函数,会严重局限内的使用。不允许复制的类的对象只能作为引用传递给函数或从函数返回,他们也不能用作容器的函数。如果定义了复制构造函数,也必须定义默认构造函数。