拷贝结构
拷贝构造又称为复制构造,是一种特殊的构造函数,它是使用一个现有的对象来构造一个新的对象,只有一个引用型的参数(对象本身)。
类名(类& )
{
}
拷贝构造的参数应该加const保护,但编译器并没有强制限制。
编译器会自动生成一个拷贝构造函数,负责把旧对象中的所有数据拷贝给新对象。
深拷贝与浅拷贝
如果类成员中有指针,浅拷贝只拷贝指针变量的值,深拷贝是指向指针变量指向的目标
什么情况下需要实现拷贝构造:
当类成员中有指针成员,此时默认的拷贝构造就无法完成任务了,需要自己动手实现拷贝构造(深拷贝)。
什么情况下会调用拷贝构造:
1. 使用旧对象给新对象赋值时
User user1 =user;
2. 使用对象当最函数的参数,当调用函数时就会一起调用拷贝构造
赋值构造
当一类旧对象给另一个类新对象赋值时,就会调用赋值构造
void operator=(类&)
{
}
什么时候会调用: 对象 = 对象;
编译器会生成一个缺省的赋值构造,它负责把一个对象的内存拷贝给另一个对象。
什么情况下会调用赋值构造:
当需要深拷贝时需要自己动手实现赋值构造,也就是拷贝构造与赋值构造需要同时实现。
编译器会自动生成四个成员函数:构造、析构、赋值、拷贝
关于拷贝构造、拷贝构造的建议
1. 缺省的拷贝构造、赋值构造函数不光会拷贝本类的数据,也会调用成员类对象和父类的
拷贝构造和赋值构造,而不是单纯的按字节赋值,因此尽量少用指针成员
2. 在函数参数中尽量使用类指针或引用当来参数(不要直接使用类对象),减少调用拷贝构造和
赋值构造的机会,也可以降低数据传递的开销。
3. 如果由于特殊原因无法实现完整的拷贝构造和赋值构造,建议将它们私有化,防止误用
4. 一旦为一个类实现了拷贝构造,那么也一定要实现赋值构造
实例:
#include <iostream>
#include <string.h>
using namespace std;
class User
{
char* name;
char pass[7];
public:
User(const char* name,const char* pass)
{
this->name = new char[strlen(name)+1];
strcpy(this->name,name);
strcpy(this->pass,pass);
}
void show(void)
{
cout << name << " " << pass << endl;
}
~User(void)
{
cout << "我是析构函数,我要释放:" << (void*)name << endl;
delete[] name;
}
private:
User(User& that)
{
name = new char[strlen(that.name)+1];
strcpy(name,that.name);
strcpy(pass,that.pass);
cout << "我是拷贝构造" << endl;
}
User& operator = (const User& that)//赋值构造
{
cout << this << " " << &that << endl;
if(this != &that)
{
// 释放旧空间
delete[] name;
// 申请新空间
name = new char[strlen(that.name)+1];
// 拷贝内容
strcpy(name,that.name);
strcpy(pass,that.pass);
/* 可以直接使用此段代码,效果相同,但不易阅读(维护)
User temp(that);
swap(name,temp.name);
*/
}
return *this;
}
};
int main()
{
User user("xiaoming","iamxm");
User user1("hhhhhhhhhhhhhhh","***");
User user2("zzzzzzzzz","xxxx");
cout << "----------------" << endl;
// 赋值构造
user = user;
user.show();
user1.show();
user2.show();
}