对象复制与赋值的解析

来源:互联网 发布:windows触摸虚拟手柄 编辑:程序博客网 时间:2024/05/22 14:53

#include <iostream>

#include <string.h>

using namespace std;

 

class MyClass

{

    public:

        MyClass(){myAge = 1;myName = "";sex = ' ';}

 

        MyClass(int age, string name, char sex):

        myAge(age),myName(name),sex(sex){}

 

        MyClass(const MyClass& copy);

        //复制构造函数

        MyClass& operator=(const MyClass& src);

        //赋值操作符

        ~MyClass(){}

 

        int getMyAge(){return myAge;}

        string getMyName(){return myName;}

        char getSex(){return sex;}

 

 

    private:

        int myAge;

        string myName;

        char sex;

 

};

 

/*1.复制构造函数依旧隶属与构造函数系列中,因此它依旧没有返回值,用类名声明

*2.复制构造函数如果没有声明,那么编译器会为你生成一个,已到达完成对象的创建

*3.如果没有复杂的继承结构,那么编译器给你生成的复制构造函数足矣胜任。不必要

*自己多此一举。编译器生成的(以此程序为例,假设没有自己定义复制构造函数):

*MyClass::MyClass(const MyClass& copy):myAge(copy.myAge),myName(copy.myName),sex(copy.sex){}

4.这参数是一个原来对象的引用,且是const的限定,这样可以消除对源对象修改的隐患。

同时也消除了“按值传递”,提高效率。

*/

MyClass::MyClass(const MyClass& copy)

{

    this->myAge = copy.myAge;

    this->myName = copy.myName;

    this->sex = copy.sex;

}

 

/*注意:MyClass& MyClass::operator=(const MyClass& src)return *this;

*/

MyClass& MyClass::operator=(const MyClass& src)

{

    if(this != &src)//避免自身的赋值

    {

        this->myAge = src.myAge;

        this->myName = src.myName;

        this->sex = src.sex;

    }

    return *this;//返回一个对象的引用,提高效率

}

int main(int argc, char ** argv)

{

    /*"复制"只会在对象创建初始化时候才会出现,这一点也从复制构造函数可见一斑。

    *任何构造函数都是在对象创建的时候,对对象进行初始化操作,离开对象创建,

    *初始化,构造函数就不会被使用,因此也就下面的“赋值”

    */

    MyClass first(23, "qwe", 'W');

    MyClass second(first);//显式调用复制构造函数

    MyClass third = second;//隐式调用复制构造函数

    cout<<second.getMyName()<<" "<<second.getMyAge()<<" "<<second.getSex()<<endl;

    cout<<third.getMyName()<<" "<<third.getMyAge()<<" "<<third.getSex()<<endl;

 

    /*当一个对象已经有值了,即是已经被初始化过了,而这个值被重写或者覆盖,那么

    *这个过程更像是“赋值”操作而不是“复制”

    */

    MyClass forth(22,"qwer",'M'),fifth;

    fifth = forth;//没有编写赋值操作符,那么编译器会给你写,因此这里不会出错,而且很成功

    //显式调用:fitth.operate=(forth);

    third = second = fifth;

    //等价于:third.operater=(second.operater=(fifth));

    cout<<forth.getMyName()<<" "<<forth.getMyAge()<<" "<<forth.getSex()<<endl;

    cout<<fifth.getMyName()<<" "<<fifth.getMyAge()<<" "<<fifth.getSex()<<endl;

 

    cout<<second.getMyName()<<" "<<second.getMyAge()<<" "<<second.getSex()<<endl;

    cout<<third.getMyName()<<" "<<third.getMyAge()<<" "<<third.getSex()<<endl;

       return 0;

}

//编译器会为定义的类定义一个默认构造函数和一个复制构造函数,如果自定义了,则

//取代相应编译器定义的构造函数。

//其中有一个特殊(也不常用,也可认为是个错误):

//自定义了复制构造函数而没有自定义其他构造函数,那么编译器不会定义任何构造函

//数,因此,这样类无法创建任何对象。

 

 

例如2:

#include <iostream>

#include <cstring>

 

using namespace std;

string fun()

{

    return ("guitar!");//构造一个临时对象,把"guitar!"复制给临时对象,离开后销毁

}

 

int main(int argc, char ** argv)

{

    string s1 = fun();//又一次复制给s1

//string s1;s1 = fun();与上面的意义不一样

    cout<<s1<<endl;

    return 0;

}

 

原创粉丝点击