2.5、拷贝构造函数与赋值函数

2.5、拷贝构造函数与赋值函数

2.5.1、拷贝构造函数

1、功能:用一个已知的对象来初始化一个被创建的同类对象。

2、缺省拷贝构造函数:

  • 如果类中没有说明拷贝构造函数,则编译器自动生成一个具有上述形式的缺省拷贝构造函数,作为该类的公有成员,来进行对象间的位拷贝。
  • 每个类都有一个拷贝构造函数

3、特点

  • 函数名同类名,无返回类型。

  • 只有一个参数,是对某个对象的常引用。

  • <类名>::<类名>(const <类名>&<引用名>) A::A(const A &a)

    4、拷贝函数分为浅拷贝和深拷贝。

浅拷贝执行的是简单的按位拷贝,而深拷贝则是当数据成员存在有动态内存开辟时(也就是用new开辟的空间时)则应该自己写一个深拷贝构造函数,而不用系统提供的缺省拷贝构造函数,因为此时如果还是浅拷贝的话,用delete时会出现问题,所以用了深拷贝。

2.5.2、赋值函数

1、功能:用一个对象给另一个对象赋值。类似于(int i = 10; int j = 20; i = j;)这种情况。

2、特点:

  • 该函数的函数名是一个操作符,必须与关键字operator合用;
  • 例:<类名>&<类名>::operator =(const <类名>&<引用名>)
  • 该函数只有一个参数,是对该类某个对象的常引用。
  • 一般赋值操作返回对被赋值对象的引用。

1.5.3、二者区别

  • 拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。
  • 创建一个新的对象,用其他对象对其赋值则调用拷贝构造函数
  • 用一个对象对另一个有值的对象赋值时则调用赋值函数
//例子
#include 
#include 
#include 

using namespace std;

class Person //驼峰命名法
{
public:
    Person();
    Person(const char *name, int age); 			//有参构造
    Person(const Person &p);					//拷贝构造函数(深拷贝)
    Person &operator=(const Person &p);			//赋值函数
    ~Person();									//析构函数(因为存在new开辟的空间内部函数体自己写的)

    void setName(const char *name);				//输入一个名字
    void setAge(int age);						//输入一个年龄

    const char *getName();						//将名字传出(接口)
    int getAge();								//将年龄传出(接口)
	
    void display() const;						//打印信息
private:
    char *m_name;
    int m_age;
};

Person::Person()
{
    m_name = NULL;
    m_age = 0;
}

Person::Person(const char *name, int age)
{
    m_name = new char[strlen(name)+1];
    strcpy(m_name, name);
    m_age = age;
}

Person::Person(const Person &p)
{
    cout << "Person::Person(const Person &p)" << endl;
    m_name = new char[strlen(p.m_name)+1];
    strcpy(m_name, p.m_name);
    m_age = p.m_age;
}

Person &Person::operator=(const Person &p)
{
    cout << "Person::operator=(const Person &p)" << endl;
    if ( this == &p) {
        return *this ;
    }

    if(m_name != NULL)
    {
        delete []m_name;
    }
    m_name = new char[strlen(p.m_name)+1];
    strcpy(m_name, p.m_name);
    m_age = p.m_age;

    return *this;
}

Person::~Person()						//释放掉挂载空间。
{
    if(m_name != NULL)
    {
        delete []m_name;
    }

}

void Person::display() const
{
    printf("m_name: %p\n", m_name);
    printf("&m_name: %p\n", &m_name);
    if(m_name != NULL)
    {
        cout << m_name << ", " << m_age << endl;
    }else
    {
        cout << "NO Name" << ", " << m_age << endl;
    }

}

void Person::setName(const char *name)
{
    if(m_name != NULL)
    {
        delete []m_name;
    }
    m_name = new char[strlen(name)+1];
    strcpy(m_name, name);
}
void Person::setAge(int age)
{
    m_age = age;
}

const char *Person::getName()
{
    return m_name;
}
int Person::getAge()
{
    return m_age;
}

int main()
{

    Person p("12345", 18);
    p.display();

    Person p1 = p;
    p1.display();

    Person p2("asdfg", 20);
    p2.display();

//    p2 = p1 = p;
//    p2.operator=(p1.operator=(p));
    p2 = p;
    p2.operator=(p);
    p2.setName("xiaohong");
    p2.display();
	return 0;
}

你可能感兴趣的:(C++)