构造函数 拷贝函数 赋值构造函数

来源:互联网 发布:百度云会员激活码淘宝 编辑:程序博客网 时间:2024/04/28 13:04

#ifndef _SAMPLE_H_
#define _SAMPLE_H_
#include <stdio.h>
#include <string>struct QQ
{
QQ() { qqNum = 123456; qqPassword = "xyzabc123"; }
int qqNum;
std::string qqPassword;
};


//以下A,B,C,D分别为:
//A: 没有实现拷贝构造函数和赋值构造函数,所以会自动生成默认的拷贝构造函数和赋值构造函数
//B: 与A相同,但数据成员存在堆分配情况,这样默认的拷贝构造函数只会拷贝指针而不会拷贝指针所指向的对象
//C: 实现了拷贝构造函数和赋值构造函数
//D: 与C相同,但存在堆分配情况,因此也必须深拷贝


//什么是深拷贝,什么是浅拷贝,自己去查下
//如果不自己去实现拷贝构造函数和赋值构造函数,那么默认就是浅拷贝。浅拷贝在类中存在指针(比如给指针new对象,即堆分配过程)时,是危险的
//因为只拷贝了指针,而不会去拷贝指针所new的对象,这样当源对象被析构时,你拷贝的指针就会指向一个已被释放了的内存


struct TA
{
TA()

tQq.qqNum = 789456;
} //struct和class的区别就是:struct所有的成员都是public的,其余一样
~TA() { }


QQ tQq;//注意,这是变量是在栈上分配内存的
};


struct TB
{
TB() 

pQQ = new QQ();
pQQ->qqNum = 789456;
}
~TB(){ delete pQQ; }//堆分配的内存一定要自己释放


QQ* pQQ;//注意,只定义了一个指针。构造函数给这个指针在堆上分配了一个对象,并把对象的地址赋给了这个指针
};


class TC
{
public:
TC() 

tQq.qqNum = 456123;
}
TC( const TC& otherC )//拷贝构造函数的形式必须这样定义
{
tQq = otherC.tQq;
}
~TC() { }


TC& operator = ( const TC& otherC )//赋值构造函数实际上就是重载"="等号操作符
{
tQq = otherC.tQq;
return *this;
}


private:
QQ tQq;
};


class TD
{
public:
TD()

pQq = new QQ();
pQq->qqNum = 123789;
}
TD( const TD& otherD )
{
pQq = new QQ();
//pQq = otherD.pQq;//思考:为什么不能这样赋值
*pQq = *(otherD.pQq);
}
~TD(){ delete pQq; }


TD& operator = ( const TD& otherD )
{
*(pQq) = *(otherD.pQq);
return *this;
}
QQ* pQq;
};

#endif

// LessonSet.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "Sample.h"
int _tmain(int argc, _TCHAR* argv[])
{
//如同默认构造函数一样,如果不定义,编译器会自动生成一个默认的拷贝构造函数和赋值构造函数
//自己调试,看它们各自调用的是什么构造函数


TA a1;  //调用默认构造函数
TA a2(a1);  //调用拷贝构造函数
TA a3 = a1;  //调用拷贝构造函数,注意:这里的等号为什么不调用=赋值操作符?
TA a4;
a1.tQq.qqNum = 1000;
a4 = a1;  //调用赋值构造函数,注意:这种赋值调用的就是=赋值操作符(赋值构造函数)


//下同


TB b1;
TB b2( b1 );
TB b3 = b1;
TB b4;
b4 = b1;


TC c1;
TC c2( c1 );
TC c3 = c1;
TC c4;
c4 = c1;


TD d1;
TD d2( d1 );
TD d3 = d1;
TD d4;
d4 = d1;


getchar();
return 0;
}

原创粉丝点击