拷贝构造
class Stu{
public:
int no;
string name;
int age;
public:
Stu(int no=10086, string name="jin", int age = 18):no(no), name(name), age(age){
}
//拷贝构造函数:由同类型的对象构造一个新的副本对象
Stu(const Stu &s){
no = s.no;
name = s.name;
agr = s.age
}
};
int main()
{
Stu s1 = (10010, "jink", 100);
//拷贝构造,但是调用的并不是Stu这个构造函数,而是拷贝构造函数
Stu s2(s1);
}
定义
由已经存在的同类型对象构造一个新的副本对象,调用的是拷贝构造函数、
-
拷贝构造函数的形式是固定不变的:
class 类名{ 类名(const 类名& 对象){ } };
本质
拷贝构造函数也是构造函数,是一个特殊
- 特殊在参数是一个同类型的对象引用
如果在实现一个类时 没有为这个类添加拷贝构造函数,则编译器会提供一个默认的
默认的拷贝构造函数是:全员复制(逐字节拷贝)副本和元对象一摸一样
程序员可以俺自己的需求构造拷贝构造函数,构造后编译器不再提供默认拷贝构造函数
使用时机
- 非引用传递对象
- 放入容器的对象都是通过拷贝构造函数
- 用存在的对象构造新的同类型的对象
调用语法
- 类名 对象1 = 对象2;
- 类名 新对象(老对象);
非默认拷贝构造函数的使用时机
- 如果需要实现深拷贝时则需要自己实现拷贝构造函数 默认的拷贝构造函数是浅拷贝
- 有指针指向动态内存时一般需要实现拷贝构造函数
- 浅拷贝——按照字节拷贝 按字节复制 拷贝对象和原对象一模一样
- 对于指针,只拷贝内存地址
- 深拷贝——对于普通数据而言没有深拷贝一说,拷贝指针所指的内容
- 对于指针,重新申请内存,把原指针指向的内容拷贝的新的内存空间中
所以当有指针指向动态内存时,一般需要使用独立构造的深拷贝
class Ptr{
private:
int *ptr;
public:
Ptr(const Ptr &pp){
}
}
拷贝赋值函数
拷贝赋值的时点
当两个已经存在的同类型对象之间的相互赋值 ,调用的就是拷贝赋值
拷贝赋值函数形如:
class 类名{
类名& operator(const 类名 &对象名){
}
}
如果一个类没有实现拷贝赋值函数,编译器提供默认的拷贝赋值函数,且为浅拷贝
若需要实现深拷贝,则需要程序员手动提供
一般来说:遵循三/五原则
- C++11之前为三:析构,拷贝构造,拷贝赋值,要么全部自己提供 ,要么全用默认
- C++11之后为五:析构,拷贝构造, 拷贝赋值,移动构造, 移动赋值
实现简单的string类
class String{
public:
//用C风格的字符串构造 String对象
String(const char *s = NULL):
str