参考网址:https://www.cnblogs.com/BlueTzar/articles/1223313.html
https://www.cnblogs.com/xiaodingmu/p/7407307.html
一、浅赋值问题
(1)如果类中叧包含简单数据成员,没有指向堆的指针, 可以使用编译器提供的默认复制构造函数
(2)如果类中包含指向堆中数据的指针,浅复制将出现 严重问题
①浅复制直接复制两个对象间的指针成员,导致两个指针 指向堆中同一坑内存区域
② 一个对象的修改将导致另一个对象的修改
③ 一个对象超出作用域,将导致内存释放,使得另一个对 象的指针无效,对其访问将导致程序异常。
二、编写自己的赋值构造函数(完成深复制的内容):实现了资源的重新分配
(1)含有指针成员的类,通常需要编写构造函数和复制 构造函数,同时需要实现相应的复制构造函数,以 及运算符重载
(2)实现“深复制”,创建对象备仹时,为新对象在堆 中分配自己的内存,并将现有值复制到新内存中。
Tricycle类举例:
第一部分:主函数:main.cpp
#include "Tricyle.h"
#include "iostream"
int main()
{
Tricycle wichita;
Tricycle dallas(wichita); //复制构造函数
wichita.setSpeed(10);
std::cout<<"Wichita ";
wichita.pedal();
std::cout<<"Dallas ";
dallas.pedal();
std::cout<<"Wichita ";
wichita.brake();
std::cout<<"Dallas ";
dallas.brake();
return 0;
}
第二部分,头文件:Tricycle.h
#ifndef TRICYLE_H_INCLUDED
#define TRICYLE_H_INCLUDED
//defination class
class Tricycle
{
public:
Tricycle(); //constructor fun
Tricycle(const Tricycle &rsh);//copy constructor fun
~Tricycle(); //disconstructor fun
int getSpeed()const{return *speed;}
void setSpeed(int newSpeed){*speed = newSpeed;}
void pedal(); //速度增加
void brake();
private:
int *speed; //在堆中申请了内存
};
#endif
第三部分:Tricycle.cpp
#include "Tricyle.h"
#include "iostream"
using namespace std;
Tricycle::Tricycle()
{
speed = new int(5);
}
Tricycle::Tricycle(const Tricycle &rsh)
{
speed = new int ; //申请动态空间,但是并没有进行初始化
*speed = *rsh.speed; //或者写成,*speed = rsh.getSpeed();
}
Tricycle::~Tricycle()
{
delete speed;
speed =NULL;
}
//速度增加
void Tricycle::pedal()
{
(*speed)++; //或者setSpeed(getSpeed()+1)
std::cout << "pedaling" << getSpeed()<<'\n';
}
void Tricycle::brake()
{
(*speed)--;
std::cout << "brakeing" << getSpeed()<<'\n';
}
运行结果:
深复制的例子:Person类
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
Person(); //缺省的构造函数
Person(const char *name, int age, char sex); //带参数构造函数
Person(Person &p); //复制构造函数构造函数
~Person(); //析构函数
void out() //输出信息
{cout<<name<<","<<age<<","<<sex<<endl;}
private:
char *name;
char sex;
int age;
};
int main()
{
cout << "***第一种情况,调用无参的构造函数"<<endl;;
Person a;
a.out();
cout << "***第二种情况,调用含参的构造函数"<<endl;
Person p1("zhangsan",20,'F'); //对构造函数进行初始化
p1.out();
cout << "***第三种情况,复制构造函数"<<endl;
Person p2(p1);
p2.out();
return 0;
}
Person::Person()
{
cout << "\t 调用了无参数的构造函数:";
name = new char[10];
strcpy(name,"haoaowei");
sex = 'M';
age = 25;
}
//带参数构造函数
Person::Person(const char *name, int age, char sex)
{
cout << "\t 调用了含参数的构造函数:";
this->name = new char[strlen(name)+1]; //加1是为存储\0
strcpy(this->name,name);
this->age = age;
this->sex = sex;
}
Person::~Person()
{
cout << "name:"<<name<<"调用了析构函数"<< endl;
delete []name;
name = NULL;
}
//复制构造函数
Person::Person(Person &p)
{
cout << "\t 调用了复制构造函数:";
name = new char[strlen(p.name)+1];
strcpy(name,p.name);
this->age = p.age;
this->sex = p.sex;
}
运行结果: