在主函数中操作, 拷贝类指针P1的方法。
A*p1=new A; //它会调用默认构造函数
A*P2=new A(*P1); //它会调用拷贝函数
这是权威回答,第二行但我是这么理解的,分解为以下三步
有个中间值 A m;
A m(*p1); 先通过*p1变成一个对象,然后调用拷贝构造函数,拷贝对象
A*P2=new Preson; 然后造一个指针
p2=&m; 然后指针指向m;
我是这么理解为指针造函数的,不知道理解的对不对。
1. 怎么会混淆呢,为什么你会认为混淆呢,两个是同一个东西,怎么混淆?对象的构造函数只会调用一个,要么调用A()那个,要么调用复制构造函数,只会执行其中的一个。怎么混淆?不同的对象,x是不同的,也就是一个对象里面包含一个x
2. 这是讲a.x指向的内容复制到x指向的内容,也就是把另一个对象的数据复制到这个对象里。如果用x=a.x,有两个问题,第一刚刚new的int的地址就没有任何变量保存了,就是内存泄露了,第二两个对象里面的指针成员指向了两个相同的东西,这样修改了其中一个另一个也会修改,销毁了其中一个另一个就是指向已回收的内存是野指针,野指针会发生各种内存访问错误问题。
3. 两者是等价的,没任何问题
Copy构造函数是显式地去处理一个对象初始化另一个对象的问题,如果类含有一个指针的话,那么处理起来主要分为两种情况。
A. 指针在类的构造或者初始化时指向动态分配的内存, 并在对象析构时对该指针进行delete操作,释放内存资源。
这种情况下,对指针的操作是万万不能简单对指针地址进行赋值操作的。应该是动态申请内存,然后按值Copy具体内容,从而防止指针指向无效内存地址的情况。
B. 指针指向一个生命周期大于该类所有对象生命周期的地址空间。
这种情况下,可以对指针直接赋值。
下面是示例代码:
#include
using namespace std;
const int nLen = 64;
// Global Variable
const char gch[] = "Hello, wangzhaohua, I't your chance.";
char gch2[] = "Global variable test";
class myClass
{
public:
myClass();
~myClass();
myClass(const myClass &); //copy contructor
void myfun();
private:
int m_na;
char *pch; //dynamic create
char *pg; //point to a global variable
};
myClass::myClass()
{
m_na = 0;
pch = new char[nLen];
memset(pch, 0x0, nLen);
int nsize = sizeof(gch);
memcpy(pch, gch, nsize < nLen ? nsize : nLen);
pg = gch2;
}
myClass::~myClass()
{
cout << "In myClass::~myClass() " << endl;
if(pch != NULL)
{
delete[] pch;
pch = NULL;
}
pg = NULL;
}
myClass::myClass(const myClass &obj)
{
cout << "In the copy-constructor " << endl;
m_na = obj.m_na + 1;
// pch = obj.pch //不能直接Copy指针的值,因为,如果obj消亡的时候,
//该指针指向的存储空间将被释放
//应该采用下面的方法
pch = new char[nLen]; //在堆上分配新的空间
memset(pch, 0x0, nLen);
memcpy(pch, obj.pch, nLen); //将obj.pch指向的内容copy过来
//obj.pg指向一个全局变量,obj消亡后,该全局变量的地址一直有效,故可以直接
//进行指针值的Copy.
pg = obj.pg;
}
void myClass::myfun()
{
cout << m_na << " In myfun() " << endl;
cout << "m_na = " << m_na << endl;
cout << "pch = " << pch << endl;
cout << "pg = " << pg << endl;
}
int main(void)
{
cout << "Now, Let's begin ..." << endl;
myClass *pObj1 = new myClass; //堆上创建一个myClass对象
if(pObj1 == NULL)
return -1;
pObj1->myfun();
//Now using the copy-constructor;
cout << " Now copy-constructor " << endl;
myClass Obj2 = *pObj1;
delete pObj1; //此时pObj1被delete,其成员指针pCh指向的内存区域无效
Obj2.myfun();
return 0;
}
A{
private:
int *x;
}
类中有一个数据成员 x,类型位int指针。
1.构造函数和复制构造函数中的x都是这个数据成员x,省略了this指针,你也可以写成this.x = new int;
在A的对象创建时,使用构造函数还是复制构造函取决于你采用何种方式初始化对象数据。
例如:
A*a=new A;//对象a使用默认构造函数A(){x=new int;*x=5;}
A b=(*a);//对象b使用复制构造函数。
2.
A(const A&a)
{
cout<<"复制构造函数执行...\n"<
*x=*(a.x); //这里*x是对指针x进行解引用,看来你对指针还是不太了解
}
3.main函数中的
A*a=new A; //a是一个执行A类型的指针,a指向新建的A对象
A b=(*a); //b是A的对象,可以使用A b(*a),调用复制构造函数
a是一个指针,*a才表示一个A的对象。
1、构造函数和复制构造函数中都出现了x=new int,那这两个x不会混淆吗?
答:这两个X都是只的定义中的 int *x这两个函数都是构造函数 所以不会同时被调用。初始化类对象的时候你只可能用到一个构造函数。
2、*x=*(a.x) 是什么意思 这里如果用x=a.x会出现什么问题?
答:*x=*(a.x)是说将a.x指向的地址对应存储空间存储的值赋值给x指向的存储空间,如果用x=a.x那么就会使x与a.x指向同一个存储空间。如果此时delete a的话 x也就没值了 相当于浅拷贝 实现不了拷贝构造函数进行深拷贝的需要。
3、A b=(*a);是什么意思 这里如果用A b(a)会出现什么问题?
A b=(*a); 使用拷贝构造函数用a初始化b
A b(a)这个就没想过后果了 你可以运行试试