您的位置:首页 > 其它

对象复制与赋值的解析

2011-05-07 09:35 309 查看
#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;
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息