拷贝构造函数和赋值函数的区别

来源:互联网 发布:大疆 知乎 编辑:程序博客网 时间:2024/06/11 01:05
// 结论:拷贝构造函数在对还没存在的对象赋值时会调用; 赋值函数在对已经存在的对象赋值会调用;赋值函数初始化前需要清理堆资源等,拷贝构造不需要。结构体有堆资源等资源要拷贝时,接的写赋值函数和拷贝构造函数,否则会得到不确定的值。

// 测试代码可直接运行

// ConstructorTest.h 文件

class ConstructorTest
{
public:
ConstructorTest();
~ConstructorTest();
ConstructorTest(char *pName);
ConstructorTest(const ConstructorTest &otherObj);  //A objA = ObjB; // 调用的是拷贝构造函数(无论类还是结构体).
ConstructorTest& operator =(const ConstructorTest &otherObj);  //  A objC; objC = objA;// 调用的是赋值函数(无论类还是结构体).
void UseConstructorTest(ConstructorTest testObj);  // 函数参数中传递对象值或者函数返回对象值时,调用的都是拷贝构造函数。
ConstructorTest GetConstructorTest(ConstructorTest &testObj);
void PrintContent();
private:
char* m_pName;

};

// ConstructorTest.cpp文件

#include <string.h>
#include <iostream>
using namespace std;
#include "classCharacter.h"


struct tagName
{
char* m_pName;
tagName()
{
m_pName = NULL;
}

tagName& operator =(const tagName& b)
{
if(m_pName != NULL)
{
delete m_pName;
}
m_pName = new char[strlen(b.m_pName) + 1];
strcpy(m_pName, b.m_pName);
cout<<"tagName operator = call !"<<endl;
return (*this);
}


tagName(const tagName &b)
{
m_pName = new char[strlen(b.m_pName) + 1];
strcpy(m_pName, b.m_pName);
cout<<"tagName Deep Constructor call !"<<endl;
}
};

ConstructorTest::ConstructorTest()
{
m_pName = NULL;
}


ConstructorTest::~ConstructorTest()
{
if(m_pName != NULL)
{
delete []m_pName;
}
}

ConstructorTest::ConstructorTest(char *pName)
{
cout<<"ConstructorTest Constructor  Call!"<<endl;
m_pName = new char[strlen(pName) + 1];
strcpy(m_pName, pName);
}

ConstructorTest::ConstructorTest(const ConstructorTest &otherObj)
{
/*if(m_pName != NULL)
{
delete [] m_pName; // 声明的时候赋值才会调用,故不用清理内存;如果清理会dump机
}*/


cout<<"ConstructorTest Deep Constructor Call!"<<endl;
m_pName = new char[strlen(otherObj.m_pName) + 1];
strcpy(m_pName, otherObj.m_pName);
}

ConstructorTest& ConstructorTest::operator =(const ConstructorTest &otherObj)
{
cout<<"ConstructorTest Assigment Constructor Call!"<<endl;

if(this == &otherObj)// 检查自赋值
{
return (*this);
}
if(m_pName != NULL)
{
delete [] m_pName;
}
m_pName = new char[strlen(otherObj.m_pName) + 1];
strcpy(m_pName, otherObj.m_pName);


return (*this);
}

void ConstructorTest::UseConstructorTest(ConstructorTest testObj)
{
ConstructorTest *pTestObj = &testObj;
pTestObj->PrintContent();
}


ConstructorTest ConstructorTest::GetConstructorTest(ConstructorTest &testObj)
{
return testObj;
}

void ConstructorTest::PrintContent()
{
cout<<"The content is: "<<m_pName<<endl;
}

void main()
{
cout<<"-------------Class Contructor Test-------------"<<endl;
ConstructorTest Name1("Sandy Ou");
Name1.PrintContent();

ConstructorTest Name2 = Name1;
Name2.PrintContent();


ConstructorTest Name3;
Name3 = Name1;
Name3.PrintContent();

Name3.UseConstructorTest(Name2);
ConstructorTest Name4 = Name3.GetConstructorTest(Name2);
Name4.PrintContent();

cout<<"-------------struct Contructor Test-------------"<<endl;
tagName nameA;
nameA.m_pName = "JesseCen";
tagName nameB = nameA;
cout<<"tagName content is:"<<nameB.m_pName<<endl;

while(1);
}

0 0
原创粉丝点击