C++类中的成员函数的三大件(Big Three):拷贝构造函数,赋值运算符重载函数,析构函数。

拷贝构造函数:用已存在类对象赋值给将要创建对象赋值,创建出新的对象。

一般定义如下:

String(const String&);//参数中的引用不能去掉,否则造成死循环。

赋值运算符重载函数:一般定义为类的成员函数,当类中有指针变量时,通常分四步走,判断是否是自赋值;是的话删除旧空间;创建新空间;用strcpy进行赋值;最终返回*this。

一般定义如下:

const String& operator=(const String&);

析构函数:当对象离开其作用域时,调用析构函数,用于销毁对象释放空间。

一般定义如下:

~String();

为什么要用三大件?主要是为了实现深拷贝。


具体代码如下:


//
//  String.h
//  BigThree
//
//  Created by student on 15/8/14.
//  Copyright (c) 2015年 personals. All rights reserved.
//

#ifndef __BigThree__String__
#define __BigThree__String__

#include <iostream>
#include <string>
using namespace std;

class String{
public:
    String(const char *str = ""); // 通用构造函数
    String(const String &another); // 拷贝构造函数
    ~String(); // 析构函数
    const String& operator =(const String& rhs); // 赋值函数
    friend ostream& operator<<(ostream& os,const String& s); // 输出运算符重载;
    
private:
    char* m_data; // 用于保存字符串
    
};

#endif /* defined(__BigThree__String__) */
//
//  String.cpp
//  BigThree
//
//  Created by student on 15/8/14.
//  Copyright (c) 2015年 personals. All rights reserved.
//

#include "String.h"
String::String (const char *str){
    if (!str) {                   
        m_data = NULL;
    }
    else{
        m_data = new char[strlen(str)+1];
        strcpy(m_data,str);
    }
    cout<<"Constructor is called!\n";
}

String::String (const String &another){
    if(!another.m_data){
        m_data = NULL;
    }
    else{
        m_data = new char[strlen(another.m_data)+1];
        strcpy(m_data,another.m_data);
    }
    cout<<"Copy constructor is called!\n";
}
String::~String(){
    if (m_data!=NULL) {
        delete [] m_data;
    }
    cout<<"Destructor is called!\n";
}

const String& String::operator =(const String &rhs){
    if(this != &rhs){          // >1判断是否是自赋值;
        delete [] m_data;      // >2 删除旧空间;
        if(!rhs.m_data){
            m_data = NULL;
        }
        else{
            m_data = new char[strlen(rhs.m_data)+1]; // >3创建新空间,并实现内容拷贝;
            strcpy(m_data,rhs.m_data);
        }
    }
    cout<<"Assignment operator overloading function is called!\n";
    return *this;  // >4返回*this,方便链式调用;
}

ostream& operator<<(ostream& os,const String& s){
    os<<"string is:"<<s.m_data<<endl;
    return os;
}


//
//  main.cpp
//  BigThree
//
//  Created by student on 15/8/14.
//  Copyright (c) 2015年 personals. All rights reserved.
//

#include <iostream>
#include "String.h"

int main(int argc, const char * argv[])
{

    // insert code here...
    String s1,s2("asdf");    //调用两次构造函数;
    s1 = s2;                //调用赋值运算符重载;
    cout<<"s1 "<<s1<<"s2 "<<s2;
    String s3=s2;           //调用拷贝构造函数(或者String s3(s2));
    cout<<"s3 "<<s3;
    //std::cout << "Hello, World!\n";
    return 0;               //最终调用调用三次析构函数,先析构拷贝构造再析构构造函数;
}


输出结果:

Constructor is called!

Constructor is called!

Assignment operator overloading function is called!

s1 string is:asdf

s2 string is:asdf

Copy constructor is called!

s3 string is:asdf

Destructor is called!

Destructor is called!

Destructor is called!

Program ended with exit code: 0