可以想想复制含指针的struct时,也要用到memcpy。
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <utility>
#include <string>
#include <string.h>
using namespace std;
class CExample
{
private:
public:
int a;
static int count;
char* str;
public:
static int getCount()
{
return count;
}
public:
#if 1 //一般类无动态成员的话,无需手动拷贝构造函数
CExample(const CExample& rhs)
{
cout<<"CExample cp()"<<endl;
a = rhs.a;
//a = 300;
//深拷贝
if(str)
{
cout<<"CExample new str"<<endl;
str = new char[a];
strcpy(str,rhs.str);
}
};
//private 修饰拷贝构造函数,编译器就不会自动生成默认的
//默认拷贝构造函数为浅拷贝,执行c2.pint = c1.pint,并未为c2.pint
//重新分配内存空间,只是和c1.pint指向相同的内存空间.在
//c1析构后,c2.pint就是野指针了.
//在拷贝构造函数重新分配内存空间为深拷贝
#endif
CExample()
{
a = 400;
count++;
}
~CExample()
{
count--;
if(str)
{
delete str;
str = NULL;
}
}
public:
CExample(int b)
{
a = b;
}
CExample(int b,char* pstr)
{
a = b;
str = new char[b];
strcpy(str,pstr);
}
void Show ()
{
cout<<a<<endl;
}
CExample& operator = (const CExample& rhs)
{
cout<<"operator()"<<endl;
a = 150;
a = rhs.a;
return *this;
}
};
void g_Fun(CExample C)
{
cout<<"g_Fun(),has cp"<<endl;
}
void g_Fun_Addr(CExample& C)
{
cout<<"g_Fun_Addr(),not cp"<<endl;
}
//g++ 不会调用拷贝构造函数
//vc 会调用拷贝构造函数
//依赖编译器
CExample g_Fun_Return()
{
CExample temp(0);
cout<<"g_Fun_Return(),has cp by vc,not cp by g++"<<endl;
return temp;
}
int CExample::count = 0;
int main (int argc,char *argv[])
{
#if 0
CExample A(100);
CExample B = A; //注意这里的对象初始化要调用拷贝构造函数,而非赋值
B.Show ();
CExample C(A);
C.Show ();
CExample D(200);
D = A; //赋值调用operator=
D.Show ();
//g_Fun(D);
//g_Fun_Addr(D);
//g_Fun_Return();
#else //深拷贝测试
char* estr = "Hello,ni hao!";
CExample E(100,estr);
cout<<"The count of CExample: "<<CExample::getCount()<<endl;
cout<<"The E.a: "<<E.a<<endl;
CExample F(E);
E.~CExample();
cout<<"The count of CExample: "<<CExample::getCount()<<endl;
cout<<"The F.a: "<<F.a<<endl;
cout<<"The F.str: "<<F.str<<endl;
#endif
return 0;
}
/*
在C++中,下面三种对象需要调用拷贝构造函数!
1. 对象以值传递的方式传入函数参数
g_Fun(D);
2. 对象以值传递的方式从函数返回
依赖编译器
3. 对象需要通过另外一个对象进行初始化
CExample B = A
*/