C++基础知识??类的复制控制
作者:网络转载 发布时间:[ 2013/4/27 9:55:45 ] 推荐标签:
引:一道经常见到的面试题 ,已知类String的原型为:
class String
{
public:
String(const char *str = NULL);// 普通构造函数
String(const String &other); // 复制构造函数
~ String(void); // 析构函数
String & operate =(const String &other);// 重载赋值操作符
private:
char *m_data;
};
请实现上述String的四个函数。
这道题涉及到了类型的复制构造函数,赋值操作符和析构函数的实现,其中有许多要注意的地方。参考c++ primer第13章
1、复制构造函数
它是一种特殊的构造函数,单个形参,该形参为对该类型的引用(常为const),当定义一个新对象并用铜类型的对象进行初始化时,将显示的调用复制构造函数,当把该类型的对象传递给函数或从函数返回该类型的对象时,将隐式的调用复制构造函数。
a、为什么形参必须为引用?考虑如下代码
class A
{
private:
int value;
public:
A(int n){value=n;}
A(A other){value=other.value;}
void functionA(){};
~A(){}
};
int main(void)
{
A a = 10;
A b = a;
b.functionA();
}
通常,这段代码会显示编译错误的,假设能编译执行,那么由于A(A other)是值传递,在执行A b = a 时,会调用A(A other)并把a当作形参复制到实参(隐式调用A(A other)),即出现了在复制构造函数中调用构造函数,形成无条件递归。所以C++标准不允许复制构造函数为值传递。正确形式应为:A(const A& other)。
b、何时需要自定义复制构造函数?
如果我们没有定义复制构造函数,编译器会为我们合成一个(即便定义了其他构造函数),默认行为为逐个成员初始化为原对象的副本。
当类中有指针,或有成员在构造时需要分配其他资源,通常需要定义复制构造函数。这其中有涉及到对象的深拷贝和浅拷贝,如果一个类拥有资源(A如char *str 指向一个字符数组),当这个类的对象发生复制过程时,资源再次分配(B:str=new char[length+1]; if(str!=NULL);strcpy(str,A.str);),这个过程是深拷贝,反之,没有再次分配资源(B:str=A.str),是浅拷贝;
类禁止复制时,需要定义复制构造函数(声明为private)。
通过以上,则String的复制构造函数可以定义如下:
String::String(const String& other)
{
int length = strlen(other.m_data);
m_data = new char[length+1]; //注意'