C++自动提供了下面这些成员函数:
复制构造函数用于将一个对象赋值到新创建的对象中,复制构造函数原型:Class_name(const Class_name &);
何时调用复制构造函数?
新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。具体的说,当函数按值传递对象或函数返回对象时,都将使用复制构造函数,按引用传递对象可以节省调用构造函数的时间以及存储新对象的空间。
//4种声明都将调用复制构造函数
StringBad ditto(motto);
StringBad metoo=motto;
StringBad alse=StringBad(motto);
StringBad * pStringBad=new StringBad(motto);
默认的复制构造函数功能:逐个复制非静态成员(成员复制也称为浅复制),复制的是成员的值。
复制构造函数造成的问题?
StringBad::StringBad(const StringBad &st){num_strings++;...} //提供一个对计数进行更新的显示复制构造函数str=new char[len+1];std::strcpy(str,st.str);//进行深度复制深度复制:复制指向的数据而不是指针。
何时使用复制构造函数?
如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针
复制运算符会出现与隐式复制构造函数相同的问题:数据受损
如何解决:
提供赋值运算符(进行深度复制)定义
className(cosnt className &)//通用格式
//假设使用new[]来初始化变量c_pointer
c_name & c_name::operator=(const c_name & cn)
{
if(this==&cn)
return *this;
delete[] c_pointer;
c_pointer=new type_name[size];
...
return *this;
}
String & String::operator=(const String & st)
{
if(this==&st)
return *this;
delete [] str;
len=st.len;
str=new char[len+1];
std::strcpy(str,st.str);
return *this;
}
C++11提供了关键字nullptr来表示空指针
String::String()
{
str="default string";
len=str::strlen(str);
}
//可改为下面任何一种形式
String::String()
{
len=0;
str=new char[1];
str=[0]='\0';
}
String::String()
{
len=0;
str=0; // str=nullptr;
}
String::String()
{
static const char * s="C++";
len=std::strlen(s);
str=new char[len+1];
std::strcpy(str,s);
}
返回引用不会调用复制构造函数,效率更高
<<运算符,必须这样做使用常规表示法来声明指向对象指针
可以将指针初始化为指向已有的对象;
*来获得对象//mem1,mem2,mem3是Classy类的数据成员
Classy::Classsy(int n,int m) :mem1(n),mem2(0),mem3(n*m+2){ ... }
初始化工作是在对象创建时完成的,请注意以下几点:
C++11的类内初始化
//与上面等价
Class Classy
{
int mem1=10;
const int mem2=20;
}