C++笔记——拷贝构造函数2

来源:互联网 发布:绵阳cnc编程招聘 编辑:程序博客网 时间:2024/06/05 14:24

编译器提供的默认拷贝构造函数的行为:

执行逐个成员初始化,将新对象初始化为原对象的副本。

“逐个成员”,指的是编译器将现有对象的每个非static成员,依次复制到正在创建的对象。

浅拷贝:创建p2时,对象p1被复制给了p2,但资源并未复制,因此,p1和p2指向同一个资源。

深拷贝:资源复制,p1和p2指向不同资源赋值运算符函数)。

何时需要定义拷贝构造函数:

类数据成员有指针;类数据成员管理资源(如打开一个文件)。

如果一个类需要析构函数来释放资源,则它也需要一个拷贝构造函数。

如果想禁止一个类的拷贝构造,需要将拷贝构造函数声明为private。

main.cpp

#include <iostream>#include "person.h"using namespace::std;int main(){    Person p("Joe");   // 调用构造函数    Person p3("tom");  // 调用构造函数    Person p2 = p;     // 调用拷贝构造函数(浅拷贝)    p.Print();    p2.Print();    p2 = p3; // 调用赋值运算符函数(深拷贝)    // 依次析构p2, p3, p    return 0;}
perison.h

#ifndef PERSON_H_INCLUDED#define PERSON_H_INCLUDEDclass Person{public:    Person(char *pName);    ~Person();    Person(const Person &s);    Person& operator = (const Person& other); // 赋值运算符函数    void Print();private:    char *name;};#endif // PERSON_H_INCLUDED

person.cpp

#include <iostream>#include <cstring>#include "person.h"using namespace::std;Person::Person(char *pN){    if(pN != NULL){        cout << "Constructing" << pN << endl;        int len = strlen(pN) + 1;        name = new char[len];        cout << "name = " << static_cast<void *>(name) << endl;        memset(name, 0, len);        strcpy(name, pN);    }else{        name = NULL;    }}Person::~Person(){    cout << "Destructing Person--->\n" << endl;    if(name != NULL){        Print();        delete []name;        name = NULL;    }}Person::Person(const Person &p){    cout << "Copy constructor of Person" << endl;    if(p.name != NULL){        int len = strlen(p.name) + 1;        name = new char[len];        cout << "name = " << static_cast<void *>(name) << endl;        memset(name, 0, len);        strcpy(name, p.name);    }else{        name = NULL;    }}Person& Person::operator = (const Person& other){    cout << "operator = " << endl;    if(&other == this)  // 防止自赋值    {        return *this;    }    if(name != NULL)   // 释放原有的资源    {        delete []name;        name = NULL;    }    if(other.name != NULL){        int len = strlen(other.name) + 1;        name = new char[len];        memset(name, 0, len);        strcpy(name, other.name);    }else{        name = NULL;    }    return *this;}void Person::Print(){    cout << "pName = " << static_cast<void *>(name) << endl;}


原创粉丝点击