C++ 9.5 复制构造函数

来源:互联网 发布:软件外包专业 编辑:程序博客网 时间:2024/05/16 04:04

接上一篇http://blog.csdn.net/wgf5845201314/article/details/64904783

9.5 复制构造函数


第七章介绍过,对于程序清单7.1 中函数Area(),传递的实参被复制:

double  Area(double InputRadius);

因此,调用Area()时,实参被复制给形参InputRadius.这种规则也适用于对象(类的实例)


9.5.1复制构造函数是一个特殊的重载构造函数,编写类的程序员必须提功能它。每当对象被复制(包括将对象按值传递函数)时,编译器都将调用复制构造函数。

为MyString 类声明复制构造函数的语法如下:

class MyString

{

    MyString(const MyString& CopySource); //copy constructor

};


MyString::MyString(const MyString& CopySource)

{

  // copy constructor implementation code

}

复制构造函数接受一个以引用方式传入的当前类的对象作为参数。这个参数是源对象的别名,您使用它来编写自定义的复制代码,确保对所有缓冲区进行深复制,如程序清单9.9所示:

#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
private :
    char* Buffer;
public :
    //Constructor
    MyString ( const char* InititialInput)
    {
        if (InititialInput != NULL)
        {
            Buffer = new char [strlen(InititialInput) + 1];
            strcpy(Buffer , InititialInput) ;
        }
        else
            Buffer =NULL ;
    }

    //copy constructor
    MyString (const MyString& CopySource)
    {
        cout <<"Copy constructor :copying from MyString "<<endl ;
        if (CopySource.Buffer != NULL )
        {
            Buffer = new char [strlen(CopySource.Buffer ) +1];
            strcpy(Buffer ,CopySource.Buffer);
            cout << "Buffer points to :ox " <<hex;
            cout <<(unsigned int*) Buffer << endl;
        }
        else
            Buffer =NULL;
    }

    //Destruction: clears the buffer allocated in constructor
    ~MyString()
    {
        cout << " Invoking destructor ,clearing up "<< endl ;
        if (Buffer != NULL)
            delete [] Buffer;
    }

    int GetLength()
    {
        return strlen(Buffer);
    }

    const char* GetString()
    {
        return  Buffer;
    }


};
//end of class MyString
void UseMyString(MyString Input)
{
    cout <<" String buffer in Mystrig is "<< Input.GetLength();
    cout <<" characters long "<<endl ;
    cout <<" Buffer contains :" <<Input.GetString() <<endl;
}

int main()
{
    MyString  SayHello("Hello from string class ");    //创建对象SayHello,调用构造函数
    UseMyString(SayHello);
    return 0;
}

输出:




main函数将SayHello按值传递给函数UseMyString(),这将自动调用复制构造函数。复制构造函数与构造函数很闲,基本思想也相同:检查CopySource.Buffer包含的C风格字符串的长度,分配相应数量的内存并将返回的值针赋给Buffer,在使用strcpy将CopySource.Buffer的内容复制到Buffer。这里并非浅复制(复制指针的值),而是深复制,即将指向的内容复制到给当前新分配的缓冲区。

两个对象Buffer指向的内存地址不同,即将两个对象并未指向同一个动态分配的内存地址。因此,函数UseMyString()返回,形参Input 被销毁时,析构函数对复制构造函数分配的内存地址调用delete[] ,而没用影响到main()中SayHello 指向的内存。因此,这两个函数都执行完时。成功的销毁了各自的对象,没有导致应用程序崩溃。











0 0