类和对象3_程序设计B

构造函数与set成员函数有什么区别?

  • set成员函数必不可缺
  • 构造函数不能完全替代set函数

1、在创建对象时,构造函数被系统自动调用,起给数据成员赋初值作用。不能在程序中显式调用。
2、可以在程序的任何地方显式调用对象的set函数,修改对象的数据成员值。
3、在对象生存周期内,构造函数只能调用一次;set函数可以被反复调用。

定义一个类:

  1. 构造函数 无参、有参
  2. set get
  3. 析构函数

this指针

用类去定义对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间。按理说,如果用同一个类定义了10个对象,那么就需要分别为10个对象的数据和函数代码分配存储单元

需要显式引用this指针的三种情况:
(1)在类的非静态成员函数中返回类对象本身或对象的引用的时候,直接使用 return *this,返回本对象的地址时,return this。
(2)当参数与成员变量名相同时,如this->x = x,不能写成x = x。
同名出现,作用域小的起作用。
(3)避免对同一对象进行赋值操作,判断两个对象是否相同时,使用this指针。

复制构造函数

复制构造函数用一个已有同类对象创建新对象进行数据初始化
C++为类提供默认版本的复制构造函数
程序员可以定义用户版本的复制构造函数
语法形式
类名 :: 类名(const 类名 & 引用名 , …);

复制构造函数的特点:

复制构造函数名与类名相同,并且也没有返回值类型。
复制构造函数可写在类中,也可以写在类外。
复制构造函数要求有一个类类型的引用参数。
如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。

以下三种情况下由编译系统自动调用:

  • 声明语句中用类的一个已知对象初始化该类的另一个对象时。
  • 当对象作为一个函数实参传递给函数的形参时,需要将实参对象去初始化形参对象时,需要调用复制构造函数。
  • 当对象是函数的返回值时,由于需要生成一个临时对象作为函数返回结果,系统需要将临时对象的值初始化另一个对象,需要调用复制构造函数。

浅复制与深复制

浅复制:
●在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容
数据成员本身拥有的空间 ——资源
●默认复制构造函数所进行的是简单数据复制,即浅复制

浅复制存在的问题:

#include <iostream>
#include <cstring>
using namespace std;
class Person 
{
public: 
	Person(char* name1,int a,double s);    
	void display(){cout<<name<<"\t"<<age<<"\t"<<salary<<endl;}
	~Person(){delete name;}		              //析构函数的声明
private:  
	 char* name;
	int age;
	double salary;
};
Person::Person(char* name1,int a,double s)           
{
	name=new char[strlen(name1)+1]; 
	strcpy(name,name1);
	age=a;
	salary=s;
}
int main()
{
Person *P1=new Person("WangWei ",8,3880); //调用构造函数创建对象P1
P1->display();
 Person P2(*P1);  //调用复制构造函数,用P1的数据初始化对象P2
	 delete P1;
 P2.display();
return 0;
}

在这里插入图片描述
深复制:
●通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
●自定义复制构造函数所进行的复制是浅复制。

定义支持深复制的复制构造函数:

  1. 深复制构造函数必须显式定义
  2. 深复制构造函数的特点
    • 定义:类名::类名([const] 类名 &对象名);
    • 成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
class Person
{
public:
	Person(char* name1,int a,double s);
	void display(){cout<<name<<"\t"<<age<<"\t"<<salary<<endl;}
	~Person(){delete name;}		              //析构函数的声明
private:
	 char* name;
	int age;
	double salary;
};
Person::Person(char* name1,int a,double s)
{
	name=new char[strlen(name1)+1];
	strcpy(name,name1);
	age=a;
	salary=s;
}

Person::Person(const Person& P0) //复制构造函数的实现
{
   	 name=new char[strlen(P0.name)+1];
	strcpy(name,P0.name);
	age=P0.age;
	salary=P0.salary;
cout<<"ff"<<endl;
}

int main()
{
Person *P1=new Person("WangWei ",8,3880); //调用构造函数创建对象P1
P1->display();
 Person P2(*P1);  //调用复制构造函数,用P1的数据初始化对象P2
	 delete P1;
 P2.display();
return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值